fix(régua): prova de mordida que não morde passa a REPROVAR - #416
Merged
Conversation
A casa tem uma lei - régua que não morde não existe - e quem demonstra a mordida é
o modo `--mutante=`. Cinco réguas imprimiam
✗ MUTAÇÃO 'x' não acendeu nenhuma cláusula — portão cego (lei 3)
e logo abaixo chamavam `process.exit(falhas.length ? 1 : 0)`. Com a lista de
falhas VAZIA - que é exatamente o caso do portão cego - o processo saía com ZERO.
Quem roda a mutação num laço e confere o código de saída, que é o jeito óbvio de
automatizar a lei, via verde justo na hora em que a régua se mostrou cega.
A prova da mordida tinha o mesmo defeito que ela existe para caçar.
As cinco passam a seguir o padrão que o telemetry-check já usava: o portão cego
entra na lista de falhas. Não inventei um sexto jeito de fazer a mesma coisa.
A MC1 varre `tools/eval/` e aceita as duas formas que a casa usa - empurrar nas
falhas ou levar uma flag até o exit -, recusando só a terceira, que é imprimir o
aviso e sair pelo `falhas.length`. Sete réguas auditadas. O mutante `exit-cego`
remove o `falhas.push` de uma delas e reprova.
Achado enquanto eu resolvia conflito nos PRs; o defeito irmão do
`eval:docsautoria` está no #415, da outra sessão.
Agent: Claude Opus 5 (Claude Code)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Collaborator
csbrasil-bot classificationNote @rubenmarcus abriu 14 arquivo(s) · +96 −21, base main. O que mudou
Labels
Ações do bot
|
rubenmarcus
added a commit
that referenced
this pull request
Aug 22, 2026
Dos 13 arquivos em conflito, 12 eram gerados e vieram da main, re-derivados depois. O único de verdade era o package.json, resolvido por união: `eval:mutcega` que a main ganhou no #416 mais `eval:animsdesvio` deste PR. E o #416, que acabou de entrar, mordeu este PR na porta: o `anims-desvio-check.mjs` nasceu com o mesmo defeito das outras cinco réguas - anunciava "portão cego" e saía por `falhas.length`, que ali é zero por definição, então a prova de que a régua morde sairia VERDE justo quando ela não mordesse. Aplicado o padrão da casa: o caso entra na lista de falhas. Nenhum arquivo de animação, de código ou de asset foi tocado. Agent: Claude Opus 5 (Claude Code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
rubenmarcus
added a commit
that referenced
this pull request
Aug 22, 2026
Dos 10 arquivos em conflito, 9 eram gerados e vieram da main, re-derivados depois. O package.json não trazia régua nova deste PR, então ficou o da main. O #416 mordeu na porta, como no #413: o `vram-check.mjs` nasceu com o mesmo defeito - anunciava "portão cego" e saía por `falhas.length`, que ali é zero por definição. Aplicado o padrão da casa: o caso entra na lista de falhas. Nenhum arquivo de textura ou de código foi tocado. Agent: Claude Opus 5 (Claude Code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
rubenmarcus
added a commit
that referenced
this pull request
Aug 22, 2026
… definir Dos 8 arquivos em conflito, 7 eram gerados. O único de verdade era o package.json - e ele quase me pegou: resolvendo pela linha do `check:`, fiquei com a lista de um lado e PERDI as DEFINIÇÕES do outro. `eval:wfsecret`, `eval:deploygate` e `eval:autofix` viraram nome órfão de uma vez. Um nome órfão mata o npm em "missing script" e TODOS os passos depois dele param de rodar - o portão pararia no meio sem ninguém perceber. Foi o segundo caso do dia: o #372 citava `eval:gelo` no `check:fast` sem nunca ter definido o script, com a régua existindo em disco e desligada. Conflito de `package.json` é o mais comum que existe aqui, porque todo PR que acrescenta régua mexe na mesma linha - então isto vai se repetir. Daí a PI: todo passo citado nos dois portões tem de estar definido (PI1) e toda régua tem de apontar para arquivo que existe (PI2). 97 citações conferidas. Os dois mutantes mordem, e ela reprova o #372 de verdade, não só o caso sintético. As três réguas desta pilha também receberam o padrão do #416, que entrou na main depois delas: prova que não morde é vermelho, não aviso. Agent: Claude Opus 5 (Claude Code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Commit-grande: merge da main na pilha de CI — 21 dos 24 arquivos são bloco gerado re-derivado Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
rubenmarcus
added a commit
that referenced
this pull request
Aug 22, 2026
… pode ter (#408) * fix(ci): classify não reprova PR de fork por secret que o gatilho não pode ter MEDIDO nos últimos 29 PRs: `classify` vermelho em 11 dos 14 vindos de FORK e em 0 dos 15 de casa. A causa não era o código de ninguém. Num PR de fork, os gatilhos `pull_request_review` e `pull_request_review_comment` rodam SEM os secrets do repositório - regra do GitHub - e o guard de identidade saía com erro. A prova é o mesmo PR, o mesmo commit, dois runs: `pull_request_target` fecha em 22s com sucesso e aplica o rótulo; `pull_request_review` morre em 4s com `GH_TOKEN` vazio. O rótulo estava certo o tempo todo; o vermelho que o colaborador via era de um run que nunca teve chance. Mesma regra que o #402 deu ao portão de autoria em clone raso: portão que não pode medir não vota. O job ganha um `if:` que o restringe aos gatilhos que enxergam secret. Para não perder o motivo pelo qual os gatilhos de review existem - reclassificar DEPOIS que o CodeRabbit comenta, o defeito da #240 - entra um sweep de meia em meia hora que roda no contexto base e reclassifica os PRs abertos por `workflow_dispatch`, caminho que tem token. O classify já dedupe rótulo e comentário, então repetir não polui o PR. A régua nova (WSEC1) varre os 14 workflows e reprova a combinação que causou isto: guard de secret junto de gatilho cego, sem `if:` que exclua o caso de fork. Os dois mutantes mordem - tirar o `if:` do classify e pôr um gatilho cego no preview-bot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Agent: Claude Code * fix(ci): quem bloqueia o PR é o build do CI, não a Vercel (#409) * fix(ci): quem bloqueia o PR é o build do CI, não a Vercel MEDIDO nos últimos 29 PRs: a Vercel reprovou 13 dos 14 PRs vindos de fork, sempre com `Authorization required to deploy.` - proteção de fork da própria Vercel, que nenhum commit do colaborador resolve. Nos PRs de casa o vermelho era build de verdade, uma vez porque o `fetch-decals.sh` não baixou o acervo (196 de 197 decalques faltando) num soluço de rede. O `ci.yml` já constrói o site em `pull_request`: o portão que importa existe e é esse. A régua nova guarda as três condições que deixam a Vercel sair do caminho crítico sem perder cobertura: DG1 o CI constrói no PR - sem isso, tirar a Vercel do bloqueio deixaria o PR sem nenhuma prova de que o site compila; DG2 nenhum `curl` do caminho do build corre sem `--retry`. `set -e` mais curl sem retry transforma soluço de rede em PR vermelho, e o autor não tem o que consertar - mesmo dano do portão que não pode medir; DG3 a etiqueta que autoriza o preview de fork é criada por quem depende dela. A DG3 achou código morto: o job `preview` do preview-bot já sabe publicar pela CLI da Vercel depois de conferir permissão do ator e SHA aprovado, mas dispara em `labeled` com `preview-autorizado` - e essa etiqueta NUNCA existiu no repositório. O bot pedia um rótulo que ninguém tinha como aplicar. Agora o próprio workflow a cria. Os dois ajustes que sobram são de painel da Vercel e não cabem no repositório; ficaram escritos no PROD-READINESS.md, com o que medir. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Agent: Claude Code * feat(ci): autofix conserta o mecânico, com lista de permissão e sem mergear (#411) * feat(ci): autofix conserta o mecânico, com lista de permissão e sem mergear MEDIDO nos últimos 29 PRs: nenhum bot deste repositório jamais commitou um conserto. Quem conserta é sempre uma pessoa. O #405 está vermelho por `DOCS1: documentação DESATUALIZADA`, cujo conserto é `npm run docs` mais um commit - trabalho sem julgamento nenhum que hoje devolve o PR para o autor. O autofix roda em `pull_request_target`, o único gatilho que enxerga secret em PR de fork (é a mesma regra que a WSEC1 passou a guardar), regenera os blocos derivados e empurra o commit. A TRAVA é o que torna isso aceitável: `autofix_allowlist.py` só libera arquivo GERADO, e o commit sai da saída dela - nunca de um `git add -A`. Encostou em qualquer outro caminho, o bot aborta e comenta. Sem a lista, o primeiro conserto errado reescreve o mapa de um colaborador e ninguém repara; com ela, o pior caso é regenerar uma doc que já era derivada. `.github/` está entre os PROIBIDOS de propósito: um bot que edita o workflow que o governa amplia a própria permissão num commit. E as ferramentas que rodam são restauradas da BASE antes de executar - PR nenhum reescreve o gerador e faz o bot executar o que ele mandar. Duas saídas sem push, porque vermelho que o autor não entende é o dano que este trabalho inteiro está atacando: fork com "allow edits by maintainers" desligado recebe o comando por comentário, e sem `CSBRASIL_BOT_TOKEN` o job avisa e sai verde em vez de reprovar. A régua AF1/AF2/AF3 guarda as três condições - escrita só depois da trava, lista sem caminho de código, e o bot NÃO mergeia (deixar pronto e fechar são coisas diferentes). Os quatro mutantes mordem. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Agent: Claude Code * fix(ci): bot marca `pronto-pra-merge` em vez de mergear sozinho (#412) A intenção declarada dos bots é autocorreção e autorrevisão para deixar o PR PRONTO - não fechar o assunto. Só que o `csbrasil-bot-automerge` chamava `gh pr merge --squash --delete-branch --auto`, e era a ÚNICA coisa que um bot deste repositório fazia sozinho: justamente a que não devia. O passo agora aplica a etiqueta `pronto-pra-merge` e comenta por que o PR está pronto. Quando o PR deixa de ser elegível, a etiqueta sai - senão ela vira um carimbo velho que ninguém confere. O botão de merge continua humano. A AF4 estende a régua do autofix para o repositório inteiro: nenhum workflow pode chamar `gh pr merge`. Ela ignora linha de comentário de propósito, para que o comentário que explica por que a chamada saiu possa citá-la. O mutante `automerge-volta` recoloca a chamada e reprova. Fora do alcance deste repositório: o Esbirro, que repetiu o mesmo alerta de `bundle-em-dia` a cada 30 minutos por 17 horas na issue #393 sem nunca agir, vive em `game3/bots/vigia-prod/plantao.mjs`. Dar ação a ele é trabalho de lá. Agent: Claude Code Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> --------- Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> --------- Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * Merge da main (alpha.175) na pilha de CI, e liga o que ela citava sem definir Dos 8 arquivos em conflito, 7 eram gerados. O único de verdade era o package.json - e ele quase me pegou: resolvendo pela linha do `check:`, fiquei com a lista de um lado e PERDI as DEFINIÇÕES do outro. `eval:wfsecret`, `eval:deploygate` e `eval:autofix` viraram nome órfão de uma vez. Um nome órfão mata o npm em "missing script" e TODOS os passos depois dele param de rodar - o portão pararia no meio sem ninguém perceber. Foi o segundo caso do dia: o #372 citava `eval:gelo` no `check:fast` sem nunca ter definido o script, com a régua existindo em disco e desligada. Conflito de `package.json` é o mais comum que existe aqui, porque todo PR que acrescenta régua mexe na mesma linha - então isto vai se repetir. Daí a PI: todo passo citado nos dois portões tem de estar definido (PI1) e toda régua tem de apontar para arquivo que existe (PI2). 97 citações conferidas. Os dois mutantes mordem, e ela reprova o #372 de verdade, não só o caso sintético. As três réguas desta pilha também receberam o padrão do #416, que entrou na main depois delas: prova que não morde é vermelho, não aviso. Agent: Claude Opus 5 (Claude Code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Commit-grande: merge da main na pilha de CI — 21 dos 24 arquivos são bloco gerado re-derivado Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> --------- Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
rubenmarcus
added a commit
that referenced
this pull request
Aug 22, 2026
…pilha DUAS COISAS, e a primeira é um resgate. 1. A fase 5 (#414, resolução automática de conflito de arquivo gerado) ficou ÓRFÃ. Ela mergeou em `fix/deixar-pronto-nao-e-mergear`, mas essa branch já tinha subido para a de cima antes — então o conteúdo mergeou para lugar nenhum. Conferido: a pilha do #408 não tinha `--caminhos` no autofix.yml nem a AF5 na régua. Trazida de volta por merge da branch original. 2. O autofix só acordava quando o PR se mexia. Mas quem desatualiza PR é a MAIN andando: 9 `chore(release)` em 20 horas, cada um reescrevendo README/STATUS/ARCH/docs e reabrindo conflito em todo PR aberto ao mesmo tempo. O bot consertava quem empurra commit e nunca quem está parado esperando revisão — que é exatamente quem precisa. Entra o gatilho `push: [main]` e um job de varredura que lista os PRs não-MERGEABLE e dispara o autofix de cada um pelo `workflow_dispatch`, o caminho que enxerga secret. A AF6 guarda isso: sem o gatilho de push, o portão acende. Os SETE mutantes mordem. As duas réguas re-mescladas também receberam o padrão do #416. Agent: Claude Opus 5 (Claude Code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Commit-grande: reúne a fase 5 órfã e acrescenta a varredura pós-release Signed-off-by: rubenmarcus <rubenmarcus.dev@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
telemetry-checkjá tinha: o caso entra na lista de falhas;tools/eval/e impede a volta.Evidência
A casa tem uma lei — régua que não morde não existe — e quem demonstra a mordida é o modo
--mutante=. Só que cinco réguas faziam isto:Com a lista de falhas vazia — que é exatamente o caso do portão cego — o processo sai com zero. Quem roda a mutação num laço e confere o código de saída, que é o jeito óbvio de automatizar a lei, vê verde justo na hora em que a régua se mostrou cega.
A prova da mordida tinha o mesmo defeito que ela existe para caçar.
Atingidas:
armas-check,docs-autoria-check,entrada-check,preload-check,replaycam-check. Otelemetry-checkjá fazia certo (falhas.push('mutacao-cega')) e serviu de padrão — não inventei um sexto jeito de fazer a mesma coisa.A MC1 aceita as duas formas que a casa usa (empurrar nas falhas ou levar uma flag até o exit) e recusa só a terceira, que é imprimir o aviso e sair pelo
falhas.length. Sete réguas auditadas; o mutanteexit-cegoremove ofalhas.pushde uma delas e reprova.Issue
Achado enquanto eu resolvia conflito nos PRs #400/#375/#372/#399. O defeito irmão —
eval:docsautoriareprovando branch de PR com autor novo — está no #415, da outra sessão; este PR não encosta nele.Risk
Só o código de saída de cinco réguas. Nenhuma cláusula de julgamento mudou.
Validation
npm run check:deploy- 31/31eval:mutcegaverde e o mutanteexit-cegoreprovandoLimite declarado
Não mexe nas cláusulas das réguas, só em como elas terminam. E não trata do
eval:docsautoria— é o #415.Bot notes
safe-automergeneeds-stagingneeds-human-gameplayneeds-human-backend🤖 Generated with Claude Code