Skip to content

fix(engine): omit what a failed PR list feeds, per state - #291

Merged
cpenaforte-clickbus merged 7 commits into
fix/pr-read-degradation-per-statefrom
fix/pr-read-degradation-failed-list
Oct 8, 2026
Merged

cpenaforte-clickbus merged 7 commits into
fix/pr-read-degradation-per-statefrom
fix/pr-read-degradation-failed-list

Conversation

@cpenaforte-clickbus

@cpenaforte-clickbus cpenaforte-clickbus commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Contexto e Motivação

Com a degradação por estado (#290), sobrou um caso que ainda inventava números: quando a listagem de um estado falha — gh pr list --state merged, a maior e a mais sujeita a timeout —, os outros estados chegam e o agregador calcula como se os PRs mergeados não existissem. A acceptance saía com 0% em todo grupo, o timeline com 0 merges por semana, o WIP subcontado. A detecção de erro transitório também casava timeout e EOF dentro de nomes de repositório e de palavras como "thereof".

Refs #236

Mudanças

  • Um estado cuja listagem falhou conta como ausente para tudo o que ele alimenta: merged → merge strategy, ciclo de vida do PR, review, cobertura humana, flow, acceptance e os merges por semana do timeline; open → todas as métricas de PR aberto, inclusive contagem e idades; flow_load, que usa todos os estados, sai quando qualquer listagem falhou (com o author_concurrency junto, para não mudar o formato que a plataforma lê).
  • A detecção de erro transitório tira o owner/name do stderr antes de casar e usa limites de palavra.
  • O aviso do relatório (EN e PT-BR) passa a citar as métricas de ciclo de vida do PR e as de PRs abertos entre as que podem faltar ou sair distorcidas.
  • docs/METRICS.md alinhado: cada célula de "nullable when" diz o estado que a alimenta, o enriquecimento parcial conta como falha, o flow sob enriquecimento parcial sai distorcido e não ausente, e a omissão do flow_load está registrada.

Plano de Teste

  • pytest tests/test_pr_fetch_degradation.py -v — listagem merged falhando com open e closed reais: nenhum campo alimentado pelos merged sai com zero; listagem open falhando: nenhuma métrica de PR aberto; listagem closed falhando: o payload igual ao limpo menos o flow_load; o fallback sem a informação por estado aplicando a união; repositório chamado timeout-svc e a palavra "thereof" sem nova tentativa, HTTP 504 e EOF com — rodado em d0ae092: 90 passed
  • pytest 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 em d0ae092: local: 446 passed; a única falha é a test_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 o test_hook_binders.py ficou de fora por depender de rede; no CI o comando literal passa

A verificação roda fora da máquina de quem construiu: o job cli do CI (RFC 0029, PM-4).

Impacto e Risco

  • Áreas afetadas: agregador, detecção de erro transitório no leitor, texto do aviso e docs/METRICS.md.
  • Compatibilidade: um run sem degradação sai byte a byte idêntico. Runs com uma listagem falhando passam a omitir o que ela alimenta; com a listagem merged falhando, a merge strategy fica ausente em vez de unknown.
  • Performance: nenhuma mudança.
  • Segurança: nenhuma superfície nova.
  • Acessibilidade e custo AWS: N/A — sem UI e sem infraestrutura.

Sobre o tamanho (RFC 0028 §2.4): 470 linhas, faixa 251–500. É o último corte das correções de engine; separar a regra da documentação que a descreve deixaria a doc errada na main.

Plano de Rollback

git revert do merge. Volta a regra só de enriquecimento e reviews por estado; nada a migrar.

Referências

Autoria Assistida

  • Agente: Claude Code — Claude Opus 5.5 nos commits, na orquestração e nas revisões finais
  • Escopo da assistência: achados da revisão final e implementação guiada por testes; a decisão de omitir em vez de estimar foi do autor
  • Revisão humana: pendente — o autor revisa antes do merge

🤖 Generated with Claude Code

cpenaforte-clickbus and others added 7 commits October 7, 2026 21:18
When `gh pr list` failed for one state while the others were read, the
PR list was not empty, so everything the missing state feeds read as a
real zero: with the merged list gone, acceptance showed 0% for every
group, the activity timeline 0 PRs merged a week, and merge strategy
"unknown" with reliable commit metrics; with any list gone, Flow Load
undercounted the WIP.

A missing merged list now omits what merged PRs feed (PR lifecycle,
review, Flow Efficiency, human coverage, acceptance, merge strategy)
and leaves the timeline's prs_merged unknown; a missing open list
omits every open-PR field; a missing list in any state omits Flow
Load. Without the per-state map the union applies, and `fetch` counts
as every list failed. Clean runs are unchanged.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The transient-error check matched anywhere in gh's stderr: "EOF"
matched "thereof", and "timeout" matched any error about a repo named
like timeout-svc, so a deterministic failure there was retried with
the pause on every page. The repo's owner/name, name and owner are
now blanked out of stderr first (only where they stand alone, so a
repo named "out" leaves "timeout" whole), and the patterns match whole
words: HTTP 5xx, timeout/timed out, deadline exceeded, connection
reset/refused, EOF. GitHub's GraphQL "may be the result of a timeout"
error is still retried. Also refresh the enrichment docstring, which
still said a page failed "even after one retry".

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nullable-when cells said "`reviews` degraded" or "`enrichment`
degraded" while the prose already gated each field on the PR state
that feeds it; the cells now carry that state, and the ones a failed
list omits say so (acceptance, funnel, timeline, PR lifecycle, Flow
Load, Flow Efficiency, coverage, open PR aging, merge strategy). §15
documents the failed-list rule, defines a stopped enrichment pass as
failed even when earlier pages came back, and says a 4xx or other
GraphQL error is not retried (GitHub's "may be the result of a
timeout" error is).

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The report caveat listed flow, review and in-PR metrics as what a
degraded read may leave missing, but a failed open list, or a failed
enrichment or reviews pass for open PRs, omits open-PR fields too. The
caveat now names them ("open-PR metrics" / "de PRs abertos"); its
opening sentence is unchanged.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
§24 listed a failed list only in the nullable-when cell. It now says
the whole series goes when `gh pr list` failed for any state (or
`fetch`), author_concurrency included, and why: the missing list would
undercount the WIP in every bucket it overlaps, and keeping only the
commit-based author count would emit buckets in a shape the platform
does not read.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Several notes still described the older PR read. The aggregate()
docstring called `prs` merged PRs, but they come in all three states.
METRICS.md §10 and the funnel module said Iris only fetches merged PRs;
it reads merged, closed and open PRs, and the limitation is that
acceptance counts only commits in merged PRs. §10 now says a failure
confined to closed or open PRs leaves acceptance and the funnel where a
clean run would have them, without implying they are always present.
§15 now says that with merged enrichment failed, Flow Efficiency is
computed over the PRs whose commit refs came back, so it is skewed
rather than missing.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed merged list omits the PR lifecycle fields (counts, time to
merge, cycle time), and a partial read skews them, but the report
caveat did not list them among what may be missing or skewed. It now
does, in both languages; its opening sentence is unchanged.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cpenaforte-clickbus cpenaforte-clickbus added type: tech-debt Código sub-ótimo conhecido, workaround, ou cleanup pendente ai-assisted PR gerado total ou parcialmente com auxílio de agente de IA (RFC 0028 §2.2.7) labels Oct 8, 2026
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
clickbus-iris Ready Ready Preview Oct 8, 2026 12:35pm UTC

Request Review

@cpenaforte-clickbus cpenaforte-clickbus self-assigned this Oct 8, 2026
@cpenaforte-clickbus
cpenaforte-clickbus merged commit b935183 into fix/pr-read-degradation-per-state Oct 8, 2026
5 checks passed
@cpenaforte-clickbus
cpenaforte-clickbus deleted the fix/pr-read-degradation-failed-list branch October 8, 2026 14:37

This branch was successfully deployed

1 active deployment
Preview — d0ae092a Deployed Oct 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted PR gerado total ou parcialmente com auxílio de agente de IA (RFC 0028 §2.2.7) type: tech-debt Código sub-ótimo conhecido, workaround, ou cleanup pendente

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant