Repository navigation
fix(harness): hook que sai cedo deixa de dar EPIPE em quem escreve o payload - #1039
Merged
Merged
Conversation
…payload O `typecheck + format + lint + test` do #1031 ficou vermelho em `post-compact-rules-reminder.test.ts:201` com `spawnSync bash EPIPE`, e o processo tinha saído com `status: 0`. Parecia flake de CI — não era. Causa: quem invoca o hook escreve o payload JSON no stdin dele. O `post-compact-rules-reminder.sh` tinha o `exit 0` da falta do log ANTES do `payload=$(cat)`: ele saía sem consumir o stdin, e o escritor levava EPIPE. O sintoma é intermitente porque o buffer do pipe (64 KB) absorve a escrita quando o payload é pequeno e o processo sai rápido. Medido em 06/10: | payload | resultado | | --- | --- | | ~60 B e ~1 KB | 5 de 5 OK | | ~70 KB e ~500 KB | 5 de 5 EPIPE | O CI falhou com ~60 bytes porque o runner deixou o script sair primeiro. Era corrida, não aleatoriedade — e foi isso que a disfarçou de vermelho de infraestrutura. A régua não estava num lugar só: dos 4 hooks que leem stdin, **3** saíam antes de drenar (`post-compact-rules-reminder.sh`, `logbook.sh`, `log-instructions-loaded.sh`). Nos três, a leitura passa para antes de qualquer `exit` — inclusive antes do `cd`, que também pode falhar e sair. Varredura depois da correção: nenhum. O gate que trava a propriedade é `tests/cleanup/hooks-drain-stdin.test.ts`, com payload de 128 KB — acima do buffer, que é o que o torna determinístico. Payload pequeno aprovaria os hooks defeituosos, exatamente como o teste existente fazia.⚠️ A PRIMEIRA versão deste gate passou 4 de 4 com o `logbook.sh` revertido ao padrão defeituoso: ela usava só um cenário — `CLAUDE_PROJECT_DIR` num diretório vazio —, e nele o `cd` do `logbook.sh` FUNCIONA, então o hook não sai cedo e o defeito não aparece. Media a fronteira errada para dois dos três. O gate roda dois cenários: | cenário | `cd` | post-compact | logbook · log-instructions | | --- | --- | --- | --- | | diretório vazio | funciona | EPIPE | ok (não sai cedo) | | diretório inexistente | falha | EPIPE | EPIPE | Provado invertido com o segundo cenário no lugar: revertendo o `logbook.sh`, o gate acusa `logbook.sh — projeto inexistente`, e só esse caso. Gate: typecheck, format:check e lint verdes; 11973 testes, fail 0, 20 skipped. Assisted-by: Claude-Code:claude-opus-5
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.
Corrige o vermelho que barrou o #1031. Parecia flake de CI; era corrida.
O que aconteceu
O
typecheck + format + lint + testdo #1031 falhou empost-compact-rules-reminder.test.ts:201:status: 0é a pista: o hook terminou com sucesso, e ainda assim oexecFileSynclançou.Causa
Quem invoca um hook escreve o payload JSON no stdin dele. O
post-compact-rules-reminder.shtinha oexit 0da falta do log antes dopayload=$(cat)— saía sem consumir o stdin, e o escritor levava EPIPE.O sintoma é intermitente porque o buffer do pipe (64 KB) absorve a escrita quando o payload é pequeno e o processo sai rápido. Medido:
O teste usa ~60 bytes e passava em toda máquina de desenvolvimento. No CI o runner deixou o script sair antes de a escrita completar.
A régua não estava num lugar só
Dos 4 hooks que leem stdin, 3 saíam antes de drenar:
post-compact-rules-reminder.sh(o que o CI pegou)logbook.shlog-instructions-loaded.shNos três, a leitura passa para antes de qualquer
exit— inclusive antes docd, que também pode falhar e sair. Varredura depois: nenhum.O gate, e o erro que ele cometeu primeiro
tests/cleanup/hooks-drain-stdin.test.ts, com payload de 128 KB — acima do buffer, que é o que o torna determinístico. Payload pequeno aprovaria os hooks defeituosos.logbook.shrevertido ao padrão defeituoso. Ela usava um cenário só —CLAUDE_PROJECT_DIRnum diretório vazio —, e nele ocddologbook.shfunciona, então o hook não sai cedo e o defeito não aparece. Media a fronteira errada para dois dos três. O gate roda dois cenários:cdProvado invertido: revertendo o
logbook.sh, o gate acusalogbook.sh — projeto inexistente, e só esse caso.Gate
typecheck✅ ·format:check✅ ·lint✅ · 11973 testes, fail 0, 20 skipped.Desbloqueia o #1031.
Assisted-by: Claude-Code:claude-opus-5