跳到正文

Blog

Releasesv0.39.0

v0.39.0 — a tela para de perguntar, e passa a dizer o que fez

This is the release note as published, not a rewrite of it. Release notes are published in the language they were written in.

Esta release é, na maior parte, uma subtração. A tela Código abria com onze decisões antes de você poder escrever uma palavra: pasta, árvore de arquivos, executor de comandos, dois seletores de segurança de três valores cada, tabela de perfis, comando de verificação, número de tentativas, modo de fusão, prévia de plano e painel de captura de tela. Quase todas eram perguntas que o sistema responde melhor do que a pessoa que só quer uma mudança feita.

Sumir da tela não é sumir do sistema

Foi por isso que apagar os controles e "deixar o padrão" seria pior do que mantê-los, e vale explicar por quê — é o raciocínio que governa a release inteira.

Postura ausente resolve no servidor para nenhuma negação de ferramenta e nenhuma pausa: mais permissivo do que qualquer canto da grade que alguém pudesse escolher. Perfil ausente faz o revisor ser o próprio modelo que escreveu o patch, que é justamente o colapso de auto-avaliação que a regra do revisor existe para impedir.

Então o app manda o que os seletores expressavam, e declara o que mandou. Acima do compositor há uma frase dizendo o que é verdade nesta máquina agora — perguntada ao sandbox, não lida da configuração. E o único caso em que a resposta honesta contradiz o que você configurou (container configurado, nenhum rodando) é preventivo: avisar que o sandbox estava fora depois de um comando já ter rodado na sua máquina é relatório, não aviso.

O comando de verificação é inferido, e o recibo diz quem escolheu

package.json (excluindo o scaffold do npm que sai com código 1 e reprovaria tudo), alvo test: no Makefile, configuração do pytest ou um diretório tests/, Cargo.toml, go.mod — e None, nunca um chute.

Nenhum modelo participa e nada é executado para descobrir. É isso que mantém evidence == "verifier" significando exatamente o que significava antes: um comando executável julgou, e o código de saída foi a autoridade.

O recibo grava verify_source, para que uma execução armazenada nunca possa ser lida como "o usuário escolheu isto". E quando não há comando nenhum, a execução diz em voz alta: esta execução é julgada por um modelo lendo a resposta, não por testes. Isso sempre foi verdade quando o campo ficava vazio. A interface é que nunca disse.

Um botão honesto

O compositor tinha dois botões, e eles não eram dois jeitos de fazer a mesma coisa. Enviar editava seus arquivos e ficava com o que quer que tivesse escrito. Executar com verificação, do lado, planejava, verificava e revertia se falhasse. Nada na tela dizia isso — então apertar Enter era silenciosamente a opção mais fraca, e Enter é o que as pessoas apertam.

O mais fraco parou de ser mais fraco. Um turno de conversa que edita agora tira um instantâneo do workspace antes, resolve o mesmo comando de verificação que uma execução resolveria, e reporta o veredito.

O desfazer é oferecido, não aplicado. Uma execução se reverte sozinha porque você pediu um veredito; uma conversa é uma conversa, e desfazer em silêncio o que alguém viu sendo digitado é uma surpresa pior do que um teste falhando. O token é de uso único.

Rodar vários agentes deixou de ser um lugar aonde se vai

O lote paralelo era um destino escolhido antes de alguém saber se o trabalho era paralelo, e fazia oito perguntas antes de fazer qualquer coisa.

Pedir várias coisas é o pedido agora. Uma lista numerada ou com marcadores, com pelo menos dois itens substanciais, propõe a divisão — de forma determinística, porque o cartão existe para você conferir a divisão, e uma divisão que precisa ser conferida não vale uma segunda inferência. Tudo que é ambíguo continua sendo um trabalho só: interromper uma mensagem comum com um cartão sobre worktrees do git é uma falha pior do que deixar passar uma divisão que você pode tornar explícita numerando as linhas.

Uma confirmação, num cartão que mostra os trabalhos e se o isolamento é real, antes de qualquer worktree existir. A tela antiga reportava "este lote rodou SEM isolamento" no banner de resultados — depois de N agentes já terem editado o mesmo diretório, que é o momento em que nada mais pode ser feito a respeito.

Quatro defeitos que a investigação encontrou ao vivo

Redesenhar obrigou a ler o que o código realmente fazia, e isso rendeu mais do que o redesenho.

  • A resolução de tiers nunca olhava quais provedores você tem. Quem tivesse só uma chave Anthropic e escolhesse qualquer perfil tinha a execução roteada para modelos que não podia chamar — em volta do único que funcionava, silenciosamente. Uma escada inteiramente inalcançável agora cai para o modelo padrão configurado, e diz que caiu.
  • A conversa afirmava que pausaria, e não podia. A frase de postura reportava pauses: "tainted" em toda superfície, mas /api/code/turn não passa nem registro de contaminação nem checkpointer. Uma conversa não tem mecanismo para parar.
  • O perfil max não conseguia terminar. O tier de topo no papel edit estourava o tempo em 3 de 3 tentativas, com patches vazios. O piloto de custeio que achou isso está em bench/role_routing/PILOT.md, junto com três retratações que ele forçou.
  • O painel "valeu a pena?" contava um passe por modelo igual a um passe por teste. Agora reporta passed_by_verifier ao lado de passed.

E um quinto, que não é bem defeito: apagar o endpoint de captura de tela removeu o único chamador de capture_local — o único lugar do código onde um host privado era alcançável de propósito. Uma exceção de SSRF deliberada saiu junto com um painel que não pertencia a uma tela de escrever código.

Também nesta release

Papéis multi-LLM com três perfis; o painel "valeu a pena?" e as quatro coisas que ele se recusa a fazer; o agente lendo AGENTS.md; o /api/runs deixando de ser um teto; eventos de ferramenta ao vivo; o mapa do repositório que estava descartando justamente o código que existia para apontar; 18 alertas do Dependabot fechados, com a triagem dita por extenso.

Nada medido mudou: 37/37 provado no snapshot de maturidade, ganho interno de 48% → 71% com n=100. Os snapshots mexem só no carimbo de versão, e dizer isso é o ponto.

Read the release on GitHub