Repository navigation
fix(engine): report which PR read steps degraded instead of hiding it - #280
Merged
Merged
Conversation
When a step of the GitHub PR read fails, the engine falls back to partial data and says nothing. Before any step can report that, the read needs a place to carry it. read_pull_requests now returns a PullRequestFetch: the PRs, plus the steps that degraded on the way. The multi-window cache stores the whole fetch, so a narrower window sliced from a wide one inherits its degradation. The `except Exception: prs = []` that cli.py and org_runner.py both inlined becomes read_pull_requests_with_fallback, which keeps the run going and marks the fetch step instead of swallowing the error. A missing gh or a missing GitHub remote is absence by design, not degradation, and stays unflagged. Refs #236 Assisted-by: Claude Code <noreply@anthropic.com> Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Each fallback in the PR fetch was silent. A failed basic pass dropped a state's PRs, a failed GraphQL enrichment left PRs without commit refs or merge-commit parents, a failed reviews pass left them without reviews - and nothing in the output said so. Two runs of the same engine on the same repo could disagree on merge strategy and flow metrics with no explanation. _fetch_prs now returns the passes that failed. The enrichment pass tells a normal end from a stop on error, including a later page failing after the first succeeded, and the reviews pass stops conflating a failure (None) with a state that has no PRs ([]). The enrichment query, which GitHub answers with intermittent 504s, gets one retry after a short pause before it gives up. Refs #236 Assisted-by: Claude Code <noreply@anthropic.com> Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
3 tasks done
2 tasks done
cpenaforte-clickbus
requested review from
clickmatos,
lucastribioliclickbus,
rafaeldearaujop and
trentas
October 5, 2026 19:28
2 tasks done
4 tasks
This branch was successfully deployed
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.
Contexto e Motivação
Quando um passo da leitura de PRs do GitHub falha, o engine cai para dado parcial e não diz que caiu. A #236 registrou dois runs do mesmo engine, no mesmo repositório e com minutos de diferença, saindo com
merge_strategy_dominant_share1.0 e 0.845 eflow_pr_countausente e 52 — por um 504 do GraphQL que nenhum campo do JSON denunciava. Quem lê não tem como distinguir "este repositório faz squash em todo merge" de "o enriquecimento falhou", que são conclusões opostas.Resolver agora porque a #215 vai reescrever esse mesmo passo da busca, e o critério de aceite dela —
metrics.jsonidêntico antes e depois — só é confiável se dois runs do mesmo código não puderem divergir em silêncio.Closes #236
Mudanças
iris/models/pull_request.py—PullRequestFetch: os PRs e os passos que degradaram (basic,enrichment,reviews,fetch). Ausência deghou de remote GitHub não é degradação: o Iris funciona sem PRs, e isso continua sem sinal.iris/ingestion/github_reader.py—_fetch_prspassa a devolver os passos que falharam; o enriquecimento por GraphQL distingue fim normal de parada por erro, inclusive quando a primeira página veio e a segunda falhou; e cada página do enriquecimento ganha uma nova tentativa após 2 s, para o 504 intermitente que o próprio código já documentava. A passada de reviews deixa de confundir falha (None) com estado sem PR ([]).iris/ingestion/window_cache.py— o cache multi-janela guarda o fetch inteiro, então uma janela estreita servida do cache herda a degradação do fetch largo de onde saiu.read_pull_requests_with_fallback— oexcept Exception: prs = []quecli.pyeorg_runner.pyrepetiam vira uma função só, que mantém o run de pé e marcafetch.A saída ainda não muda: o sinal é produzido e testado aqui, e emitido no
metrics.jsone no relatório pelo PR empilhado sobre este.Plano de Teste
pytest tests/test_pr_fetch_degradation.py tests/test_window_cache.py -v— 24 testes:ghfalso que lançaCalledProcessError, como o real comcheck=True; retry que recupera e que não recupera; segunda página falhando depois da primeira; resposta semdata; reviews[]contraNone; união dos passos entre os três estados; cache preservando a degradação; e a ausência deghou de remote sem sinal nenhum — rodado emb4a936e: 24 passedpytest tests/ -q— a suíte inteira, com o portão de determinismo da [FEAT] Comparador de paridade do metrics.json, campo a campo #214 — rodado emb4a936e: local: 359 passed; a única falha é atest_status_reflects_state([BUG] test_agent_settings_hook lê o spool real — falha em máquina com registros pendentes #146), que só ocorre fora do CI, e otest_hook_binders.pyficou de fora por depender de rede; no CI o comando literal passaA verificação roda fora da máquina de quem construiu: o job
clido CI executapytest tests/ -qa cada push (RFC 0029, PM-4).Impacto e Risco
github_reader.py,window_cache.py) e os dois pontos de entrada que a chamam (cli.py,org_runner.py).metrics.jsonde qualquer run sai idêntico ao de hoje.read_pull_requestsmuda o tipo de retorno delist[PullRequest]paraPullRequestFetch; os dois únicos chamadores do repositório estão atualizados.Sobre o tamanho (RFC 0028 §2.4): 470 linhas, faixa 251–500. O tipo novo e a detecção que o preenche formam um contrato só: separá-los deixaria na
mainumPullRequestFetchcujo campo de degradação nunca é preenchido. A #236 já foi dividida em PRs empilhados justamente por tamanho.Plano de Rollback
git revertdo merge deste PR. Sem migração, sem feature flag, sem estado a desfazer. Se os PRs empilhados sobre este já tiverem entrado, eles são revertidos antes.Referências
mainAutoria Assistida
🤖 Generated with Claude Code