fix(gate): fecha o lote de issues do protocolo e endurece o gate - #33
Merged
Conversation
Pathspec staging, pins de ferramenta, dual checkpoint, empty-suite e tsc --noEmit mais seguros; CI pinado em bash 3.2; suite 103/103.
Collaborator
Author
|
@coderabbitai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aa38f9ec2b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Empty-suite YELLOW only for runner exit 1 with no post-empty failure lines; close hygiene no longer deletes user-tracked knip reports.
O gate classifica um repo em GREEN/YELLOW/RED, e GREEN autoriza delecao autonoma de codigo morto. Estes oito caminhos davam o veredito errado. Fail-open (davam GREEN sem suite alguma ter rodado): - `--passWithNoTests`: o runner sai 0 sem rodar teste e a deteccao de suite vazia so existia no ramo de exit nao-zero, entao esse caso nunca era visto. - node:test: o runner nativo nao imprime nenhuma das frases conhecidas; numa execucao vazia sai 0 e reporta `tests 0` (spec) ou `# tests 0` (TAP). - Ruby: `spec/` e `test/` contavam como suite pela existencia do diretorio. Um `spec/` so com `spec_helper.rb` alcancava GREEN. Fail-closed (mandavam RED onde o contrato promete YELLOW cap): - Suite vazia em pnpm/yarn/bun: o epilogo do proprio gerenciador era lido como falha real. pnpm mudou a linha entre majors (v9 `ELIFECYCLE Command failed`, v10/v11 `[ELIFECYCLE] Test failed.`) e as duas formas contam. Contrato de exit code: - `timeout -k` finaliza com SIGKILL um check que ignora TERM, e o shell reporta 137, nao 124: um check travado era anunciado como quebrado. A decisao passa a viver em wd_timed_out(). Portabilidade e robustez: - awk `IGNORECASE` e extensao do gawk, ignorada por BSD awk e mawk — as duas pernas do CI. O guard de falha encadeada so pegava a capitalizacao exata das fixtures; agora usa tolower(). - A captura da saida do teste virou arquivo em vez de `$()`: um neto destacado herdando o stdout segurava o pipe e travava o gate pela vida inteira dele, com o GATE_TIMEOUT vencido e o watchdog impotente. - Ruby: `test/test*.rb` e o pattern DEFAULT do Rake::TestTask, entao aceitar so o sufixo `*_test.rb` tornava uma suite minitest real invisivel. Suite: 105 -> 124 casos, 145 -> 151 invariantes. Cada correcao tem regressao provada RED->GREEN contra uma variante do gate.sh sem aquele fix. Verificado sob /bin/bash 3.2 (piso do CI); shellcheck -S warning limpo. Claude-Session: https://claude.ai/code/session_01JnxsVonNUHPD6wcmi2TnFJ
O runner macOS nao traz GNU timeout, entao os dois casos do caminho -k so executavam no Linux e o total caia de 124 para 122 la. coherence_test.sh secao 9 compara esse total com o numero publicado nos READMEs, entao a mesma arvore ficava verde num runner e vermelha no outro — com a doc certa no primeiro e mentirosa no segundo. O skip agora conta como caso e imprime o motivo, entao o numero publicado vale nos dois ambientes sem afirmar que a escalada foi exercitada onde ela nao existe. Claude-Session: https://claude.ai/code/session_01JnxsVonNUHPD6wcmi2TnFJ
O cap existia e era inerte contra os dois runners que a doc nomeia. Ambos imprimem o código na própria linha — "No test files found, exiting with code 1" — e depois continuam se explicando: o vitest lista include/exclude, o jest diz quantos arquivos checou e cada testMatch que tentou. A guarda anti-falha- encadeada lia essa cauda como um segundo comando que falhou, então todo repo JS/TS sem arquivo de teste ia para RED enquanto SKILL.md e os dois READMEs prometiam YELLOW. O que a linha diz sobre a saída vale mais do que o que vem depois dela: quando ela nomeia o código e é o código com que o processo saiu, a saída está explicada e a cauda é diagnóstico. Sem código inline, a regra estrita continua valendo. Isso sozinho abriria uma porta: qualquer falha encadeada que saísse 1 passaria como suíte vazia. Por isso a blacklist de falha ganhou 'error'/'ERR!' — um build que quebrou depois da suíte vazia imprime erro e continua RED. As fixtures antigas emitiam uma linha só, e é por isso que a guarda podia estar errada aqui e verde lá. As três novas reproduzem a saída real do vitest 3 e do jest 29 byte a byte, mais o caso do erro encadeado; sem o fix, as duas primeiras falham.
This was referenced Aug 9, 2026
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
Fecha o lote de issues fechadas #7–#16 e #24–#31: protocolo de pathspec staging (nunca
git add -A), pins de ferramentas (knip@6.32.0,fallow@3.14.0,jscpd@5.0.14), dual checkpoint (fase 2 domínio + fase 3 plano), caps de stack, abort se hook bloquear rollback, e gate mais seguro para empty-suite /tsc --noEmit.Why
O protocolo e o gate precisavam fechar buracos reais: suíte quebrada classificada como YELLOW por substring,
tscpromovido via comentário# --noEmit, staging cego engolindo artefatos locais, e docs prometendo GREEN/autonomia onde o contrato agora exige checkpoint ou YELLOW.How to verify
bash scripts/test.sh # esperado: 127/127 cases, 5/5 properties, 151/151 invariantsChanged
scripts/gate.sh,gate_test.sh,coherence_test.sh,test.shSKILL.md,README.md,README.en.mdreferences/*(audit, duplication, knip-config, other-stacks, phase-2/3).github/workflows/ci.yml(assert/bin/bash3.2)Closes #7
Closes #8
Closes #9
Closes #10
Closes #11
Closes #12
Closes #13
Closes #14
Closes #15
Closes #16
Closes #24
Closes #25
Closes #26
Closes #27
Closes #28
Closes #29
Closes #30
Closes #31
Revisão (2026-08-09)
Uma revisão independente encontrou 1 bloqueante, corrigido em
9a2b459:O cap de suíte vazia JS/TS (#24) era inerte contra vitest e jest reais.
Ambos imprimem o código na própria linha (
No test files found, exiting with code 1) e depois continuam se explicando — vitest lista include/exclude, jestdiz quantos arquivos checou. A guarda anti-falha-encadeada lia essa cauda como
um segundo comando falhando, então todo repo JS/TS sem arquivo de teste ia
para RED enquanto a doc prometia YELLOW. As fixtures antigas emitiam uma linha
só, e por isso o invariante ficava verde sobre o bug.
Correção: quando a linha nomeia o código e é o código com que o processo saiu,
a saída está explicada e a cauda é diagnóstico. A blacklist de falha ganhou
error/ERR!para que isso não vire porta de entrada de qualquer falhaencadeada que saia 1. Três fixtures novas reproduzem vitest 3 e jest 29 byte a
byte, mais o caso do erro encadeado — sem o fix, as duas primeiras falham.
Os não-bloqueantes viraram issues #35–#42 (ANSI quebrando a classificação,
falha encadeada silenciosa, invariantes que ficaram em prosa, marcadores
vacuosos, escopo do
git add -A, regressão só-Linux, buffer da saída JS,custo do coherence isolado).