Lote 3: os sete defeitos de comando do milestone 3 - #32
Merged
Conversation
O pipeline prescrito usava --format=%H --name-only, que joga o hash do commit e a linha separadora no mesmo fluxo dos nomes de arquivo. O uniq -c contava os tres como se fossem arquivos: a linha em branco liderava o ranking e cada SHA empatava em 1 com os arquivos raros. audit.md pedia os '20 mais modificados' sem dar receita nenhuma, entao recebeu o mesmo one-liner corrigido em vez do convite a rederivar o quebrado. Closes #17
O redirecionamento direto abria e truncava knip-report.json antes de o knip comecar, entao qualquer falha (config quebrada, plugin, OOM) apagava o relatorio anterior e deixava um arquivo vazio, que o passo 1.3 le como 'nada a deletar'. Falha silenciosa em vez de erro visivel. Passa a escrever em .tmp e mover so em caso de sucesso. --no-exit-code e o que torna o && utilizavel: knip sai 1 sempre que encontra algo, que e o caso normal aqui, e 2 so quando de fato falhou. Comando byte a byte igual nos dois arquivos. Closes #21
…r deps As tres categorias liam um knip-report congelado. Elas se alimentam: apagar arquivo orfao mata export que o relatorio ainda via vivo e libera dep que via usada, e export listado como morto pode estar em arquivo ja removido pela categoria anterior. O ciclo passa a regenerar o relatorio depois do commit de cada categoria, e a contagem final vira estado medido. Tirar a entrada do package.json nao tira o pacote do node_modules e o gate nunca instala, entao typecheck e teste passavam com a dep removida por engano e a quebra so aparecia na CI. O protocolo passa a rodar o install simples do package manager antes do gate, com o lockfile entrando no commit da categoria. Forma congelada fica de fora: --frozen-lockfile e --immutable recusam manifesto podado, e npm ci deixa o lockfile obsoleto (medido em npm 11 e 12: sai 0, mas nao reescreve o lock). gate.sh nao muda. Inclui o mkdir -p no exemplo de git mv da fase 3 (parte de #18), para casar com references/phase-3-structure.md. Closes #19, closes #20
O exemplo canonico de movimentacao nao criava o diretorio de destino, e a fase 3 existe justamente para aplicar uma estrutura que ainda nao existe: git mv para diretorio inexistente morre com exit 128, e o agente rodando sem supervisao le isso como passo que falhou, ou parte para mv + git rm, que a propria doc proibe por atrapalhar a deteccao de rename. Secao 6 do coherence_test amarra as duas coisas: todo arquivo de protocolo com linha de comando git mv precisa do mkdir -p na linha imediatamente acima. Mencao em prosa nao conta (ancora em ^git mv). Piso derivado no mesmo estilo da secao 4. O item nao entrou na lista 'Do not forget': aquela lista e sobre o que aponta para caminho antigo e quebra em silencio; diretorio faltando aborta alto, antes de mover, e e lido depois do fato. Ficou junto do comando. Closes #18
O gate so reconhecia scripts com nome exato typecheck e test, entao projeto com type-check ou test:unit caia em exit 3 e exigia gate manual mesmo tendo rede de seguranca completa. Falhava fechado, nunca dava verde falso, mas custava a autonomia que a skill promete. Passa a aceitar typecheck/type-check/tsc/check-types e test/test:unit, com o primeiro nome definido pelo projeto vencendo e os demais ignorados. O que chega em run() e o KIND, nunca o apelido: run() classifica por kind, e nome cru ali faria o check rodar, passar e nao contar, caindo em exit 3 do mesmo jeito. checks= mantem o vocabulario canonico; o apelido aparece so na linha humana. bash 3.2, sem arrays. 6 casos novos no gate_test (57 -> 63), incluindo o ramo yarn com lockfile, que ate agora nao tinha teste nenhum. Closes #23
…contecer A tabela admitia 'tests exist but fail' em YELLOW e prometia rodar a fase 1 em deps e orfaos. Mas o gate sai 1 em qualquer check vermelho e o passo 1.3 exige gate verde antes de cada commit: com suite vermelha preexistente todo gate falha, o protocolo manda reverter e seguir, e nenhuma categoria commita. A skill anunciava YELLOW, gastava rodadas de knip e delecoes, e entregava zero commits com tudo marcado como falha. YELLOW passa a ser rede parcial, igual ao que os READMEs ja diziam, e baseline vermelho vira RED com diagnostico: sem verde inicial nao da para separar o que a faxina quebrou do que ja estava quebrado. Os READMEs tambem paravam de mencionar que a fase 2 trava no checkpoint no nivel GREEN - corrigido nos dois. Secao 7 do coherence_test amarra as tres tabelas: mesma sequencia de niveis nos tres arquivos e condicao canonica de YELLOW na linha da tabela, com o PT casando a versao em portugues. O grep orfao do Step 0 e a redacao antiga de YELLOW entraram na lista de strings mortas da secao 3. Tambem remove o grep de package.json do Step 0 (resto de #23): nenhum dos tres paragrafos seguintes o consumia, o papel passou para o gate.sh, e ele casaria o nome de uma dependencia chamada 'test'. Closes #22
Os numeros gravados (57/57, 5/5, 49/49) estavam corretos na base desta branch e foram invalidados por ela: os casos do gate foram a 63 com os apelidos de script, e os invariantes a 61 com as secoes 6 e 7.
O mais grave: a secao 7 do coherence_test era vazia para a propria regressao que motivou a #22. O colapso de repeticoes consecutivas fazia GREEN,YELLOW,YELLOW,RED ler como 'GREEN YELLOW RED', entao trocar a linha RED por YELLOW passava 61/61 verde. Agora ancora na tabela de niveis e checa a condicao canonica de YELLOW e de RED. Secao 6 estava rigida e frouxa ao mesmo tempo: exigia mkdir -p na linha imediatamente acima (reprovava um mkdir servindo dois moves, que e a forma natural) e ancorava em coluna 0 (comando indentado dentro de lista passava invisivel). Vira cobertura por bloco, sem ancora de coluna, com IFS preso em newline para nao quebrar em caminho com espaco. gate.sh: a string com dois-pontos vira run_first <kind> <nomes>, sem split sem aspas e sem o comentario que dizia 'sem arrays' num arquivo que ja usa array indexado. Comportamento identico. SKILL.md: exit 1 nao emite linha checks=, entao classificar por ela nao funcionava no vermelho; a validacao do relatorio passa a checar a ausencia do .tmp, que e o unico sinal que distingue relatorio fresco de relatorio velho; knip-report entra no .git/info/exclude para o git add -A nao commitar artefato da ferramenta no repo do usuario; o install entra na linha da sequencia de 1.3, nao so no paragrafo 20 linhas abaixo. audit.md e phase-2-consolidation.md: --since restaurado no ranking de churn, que tinha perdido a janela de 6 meses da propria frase. Suite 61 -> 66 invariantes, com os dois extratores novos ganhando autoteste na secao 0.
Dois defeitos na lista de apelidos introduzida em 5f35d14. tsc como nome de script normalmente e compilacao com emissao, nao check. O gate escreveria .js/.d.ts/.tsbuildinfo ao lado dos fontes da arvore que esta julgando, o git add -A do passo 1.3 levaria isso para o commit da faxina, e o rollback documentado (git restore --staged --worktree .) nao remove arquivo untracked. Ficam typecheck, type-check e check-types, que nao sao ambiguos. test:unit contava como suite canonica sem olhar o resto do manifesto, entao projeto com test:unit e test:e2e e sem test ia a GREEN tendo rodado so a fatia unitaria - e GREEN e o que libera delecao de export e as fases 2 e 3. Agora test simples sempre vence; na ausencia dele, um test:* so conta se for o unico. Com duas ou mais fatias o gate nomeia as que achou, nao conta nenhuma, e o projeto cai no teto YELLOW, que e o veredito honesto para uma suite que ele nao consegue rodar inteira. Regra generalizada para qualquer test:*, nao so test:unit: projeto cujo unico ponto de entrada e test:integration continua funcionando, que era o ganho de autonomia da #23. 5 casos novos (63 -> 68), incluindo check-types, que nao tinha fixture nenhuma e podia ser removido da lista sem nenhum teste reclamar. O caso js-alias-tsc virou fixture anti-regressao do comportamento oposto.
Defeito introduzido pela regra do test:* unico: script de watch era
promovido a suite inteira. Com {typecheck, test:watch} o gate rodava
npm run test:watch, que nunca termina, e saia 4 depois de 900s - que a
SKILL.md define como 'rede nao pode ser medida, nao rode sozinho'.
Reproduzido com GATE_TIMEOUT=3. test:watch, test:ui e test:debug ficam
de fora da promocao.
O ramo de multiplas fatias imprimia linha propria em vez de passar pelo
no_tests(), entao nunca emitia o marcador 'test' not counted que a
SKILL.md manda usar para classificar - o agente nao distinguia essa
YELLOW de um stack genuinamente sem suite, e o conselho de promover a
mao estava exatamente invertido. E js_test_script descartava o exit do
node: qualquer falha depois da sonda de parse virava string vazia, sem
diagnostico, o unico caminho mudo do script inteiro. Agora imprime e
seta incomplete.
coherence_test: o invariante do mkdir so exigia que ALGUM mkdir -p
precedesse o move, nao que ele criasse o destino daquele move - plano
com duas pastas passava verde com o segundo git mv morrendo em 128.
Dois autotestes eram vazios (provado por mutacao: apagar cada regra
mantinha a contagem) e level_row casava o nivel em qualquer lugar da
linha, entao prosa citando outro nivel sequestrava a assercao.
Secoes 8 e 9 novas: comandos canonicos de knip e churn, e a contagem de
casos dos READMEs derivada do gate_test - que e a classe de drift que
produziu o numero errado no commit 8403489 (63 gravado, 68 real).
Docs: vocabulario de apelidos e fatias documentado (so existia em
comentario do gate.sh), bullet RED dos limites conhecidos nos dois
READMEs ainda trazia a definicao antiga, .git/info/exclude nao cobre
arquivo ja rastreado, node_modules reinstalado antes do git add -A em
repo que depende de gitignore global, e o .tmp que faltava no passo 6
do knip-config.
Suite 68 -> 70 casos e 66 -> 77 invariantes.
O cap de suite fatiada era derrotado em repo poliglota: outro stack fornecia test, checks= lia typecheck,test e o gate anunciava GREEN com a suite JS inteira sem ter rodado. Mesma classe para go, rust, .NET e o pytest-5, porque no_tests nao setava nada que o veredito lesse. uncounted_suite() passa a marcar todo cap de stack inteiro, e o veredito recusa GREEN quando a marca esta ligada, dizendo por que. O cap por projeto do .NET fica no no_tests simples: projeto sem teste ao lado de outro com teste e normal. MUDANCA DE COMPORTAMENTO: repo poliglota que antes lia GREEN passa a capar em YELLOW quando qualquer stack ficou descoberto. Modulo Go sem *_test.go ao lado de app JS testado e o caso tipico. Outros achados do proprio codigo novo: a exclusao de watch era ancorada no fim, entao test:watch:all voltava a ser promovido e o gate travava ate o timeout; fatia com comando vazio era filtrada por truthiness e duas metades viravam uma so, devolvendo GREEN; run_first tratava qualquer exit nao-zero do node como 'script nao definido' e derrubava o typecheck em silencio - a mesma assimetria que a rodada anterior tinha corrigido do lado do teste, um bloco abaixo. Manifesto sem nenhum script de teste tambem nao emitia marcador nenhum, entao a frase da SKILL.md sobre classificar por 'test' not counted era falsa. coherence_test: gitmv_orphans lia o destino como , entao git mv -f, caminho com aspas ou move de varias fontes eram checados contra o token errado; level_rows ancorava na primeira linha com | citando um nivel, e tabela vizinha sequestrava o extrator. Secao 9 contava 70 call sites dos quais 10 vivem atras do guard de perl - a premissa agora esta escrita. audit.md: a justificativa do --no-merges estava factualmente errada sobre o git (log --stat nao imprime arquivo de merge por padrao); vale o aviso contra -m no lugar dela. Suite 70 -> 75 casos.
A quarta passada auditou o que a terceira escreveu, e o uncounted_suite
tinha cinco veredictos falsos.
Regressao contra usuario existente, a mais grave: os caps novos de Python
e Ruby disparavam nos marcadores mais frouxos do script - requirements.txt
ou Gemfile soltos. Repo JS verde com um requirements.txt do build da doc
passava a capar em YELLOW para sempre, sem resposta possivel, quando antes
lia GREEN. Os caps agora exigem fonte .py de verdade, ou .rb com gemspec.
.NET por projeto chamava no_tests puro, entao stack .NET onde NENHUM
projeto tem teste nunca marcava uncounted e ainda anunciava GREEN - o
buraco exato que a marca existia para fechar. Vira acumulador
dotnet_counted; cap por projeto ao lado de projeto com teste continua
sendo no_tests simples, que e o caso normal.
JVM usava run both, que conta test incondicionalmente: pom.xml sem
src/test dava GREEN, e mvn -q test sai 0 em modulo sem classe de teste.
Ganhou varredura de evidencia de fonte de teste.
ui estava no mesmo denylist de watch e debug, mas denylist tira a fatia
da CONTAGEM, nao so da execucao: {test:unit, test:ui} virava fatia unica e
subia a GREEN com a metade de UI sem rodar. watch e debug sao modo da
mesma suite; ui e escopo proprio. Agora ui nao roda mas conta.
E o veredito com elif descartava metade da mensagem quando os dois caps
batiam junto - os testes so grepavam a substring YELLOW, presente nas
duas, entao nada reclamava.
Docs: npm ci nao 'aceita a remocao', ele falha com EUSAGE em manifesto
dessincronizado (a rodada 1 tinha medido npm 12 e escrito o contrario);
.git/info/exclude vira git rev-parse --git-path, que e o unico que
funciona em worktree e submodule; o find -type d -empty -delete da fase 3
era varredura cega em src/ e virou rmdir por nome.
11 casos novos (75 -> 86), um por defeito. A fixture jvm-hybrid ganhou
src/test/java: ela passava pegando carona no bug.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
5 tasks
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.
Fecha as sete issues do milestone "Rodada 2 - lote 3". São defeitos de comando: coisas que o agente executa e que falham, ou que passam quando deveriam falhar.
Fecha #17, #18, #19, #20, #21, #22, #23.
Duas mudanças de comportamento
Estas atingem repo real e não são refactor. Leia antes de mergear.
Repo poliglota não recebe mais GREEN se algum stack ficou sem suíte contável. Módulo Go sem
*_test.goao lado de um app JS testado é o caso típico: antes lia GREEN, agora capa em YELLOW. O veredito diz qual cap disparou. Isso fecha boa parte da #25, mas sem granularidade por stack nochecks=— comentei lá o que ficou de fora.Baseline vermelho virou RED, era YELLOW. Com a suíte já quebrada o gate nunca fica verde, e como todo commit exige gate verde, a skill anunciava YELLOW, gastava rodadas de knip e deleções, e entregava zero commits com tudo marcado como falha. O script de teste que o
npm initescreve cai nesse caminho, e nenhuma doc avisa — está na #29.O que cada issue era
#17 — o pipeline de churn usava
--format=%H --name-only, então o hash do commit e a linha separadora entravam no mesmo fluxo dos nomes de arquivo. Num repo de 4000 commits a linha em branco liderava o ranking e os 4000 SHAs empatavam com os arquivos raros.#18 — o exemplo de
git mvnão criava o diretório de destino, e a fase 3 existe para aplicar uma estrutura que ainda não existe. Exit 128, que o agente rodando sozinho lê como passo que falhou.#19 — as três categorias da fase 1 liam um
knip-report.jsoncongelado. Elas se alimentam: apagar órfão mata export que o relatório via vivo. Agora o relatório é regenerado depois do commit de cada categoria.#20 — tirar a dependência do
package.jsonnão a tira donode_modules, e o gate nunca instalava. Typecheck e teste passavam com a dep removida por engano, e a quebra aparecia na CI. O protocolo passa a rodar o install simples antes do gate, com o lockfile no commit da categoria.#21 — o redirecionamento truncava o
knip-report.jsonantes de o knip começar, então uma falha apagava o relatório anterior e deixava um arquivo vazio que o passo 1.3 lia como "nada a deletar".#22 — a linha YELLOW da tabela prometia commits que o gate nunca deixaria acontecer.
#23 — o gate só reconhecia scripts com nome exato
typechecketest. Projeto comtype-checkoutest:unitcaía em exit 3 e exigia gate manual mesmo tendo rede completa. Agora aceitatype-check,check-typese uma fatiatest:*quando ela é a única.tscficou de fora da lista de propósito: como nome de script normalmente é compilação com emissão, e o gate escreveria.js/.d.tsna árvore que está julgando, que ogit add -Ado 1.3 levaria ao commit — e o rollback documentado não remove arquivo untracked. O custo disso está na #27.Revisão
Quatro passadas de
/code-review max --fix, 60 achados. As rodadas 2, 3 e 4 auditaram quase só o código que o--fixda rodada anterior tinha escrito, o que valeu a pena: a rodada 4 pegou uma regressão contra usuário existente que a 3 havia introduzido — repo JS verde com umrequirements.txtdo build da doc ficava capado em YELLOW para sempre.O que não foi consertado virou issue: #24, #25, #26, #27, #28, #29, #30, #31.
Verificação
bash scripts/test.shem bash 5 e no/bin/bash3.2 do macOS:shellcheck scripts/*.shsem achado novo,bash -nlimpo.Os dois invariantes novos foram provados por mutação, e os autotestes deles também: dois eram vazios na primeira escrita e passavam verde com a regra apagada. A seção 7 nasceu vazia para a própria regressão da #22 — reverter a linha RED para YELLOW passava 61/61 — e isso só apareceu na primeira revisão.