Skip to content

fix(engine): surface PR read degradation in metrics and the report - #281

Merged
clickmatos merged 4 commits into
mainfrom
fix/pr-read-degradation-report
Oct 8, 2026
Merged

clickmatos merged 4 commits into
mainfrom
fix/pr-read-degradation-report

Conversation

@cpenaforte-clickbus

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

Copy link
Copy Markdown
Contributor

Contexto e Motivação

A leitura de PRs já sabe quais passos degradaram (#280), mas nada fora dela fica sabendo: o metrics.json e o relatório seguem apresentando dado parcial com a mesma confiança do completo. E a merge strategy faz pior do que omitir: sob enriquecimento degradado, a heurística de fallback só consegue responder squash, então um repositório misto aparece como squash 100%, com as métricas por commit marcadas como não confiáveis — o oposto da verdade. Como o dashboard mostra o run mais recente, um único run degradado basta para o repositório aparecer assim.

Resolver agora porque é esta parte que torna o sinal visível: sem ela, a anterior não muda nada para quem lê o relatório.

Refs #236

Mudanças

  • ReportMetrics.pr_enrichment_degraded — os passos que falharam, em ordem e sem repetição. Omitido do JSON quando nada degradou, então um run limpo gera o mesmo metrics.json de antes.
  • aggregate(..., pr_fetch_degraded=...) emite o campo, e cli.py e org_runner.py passam o que a leitura reportou — também nos agregados da janela recente e de antes e depois da adoção, porque o metrics.json serializa esses dois últimos em adoption_timeline.
  • detect_merge_strategy(..., enrichment_degraded=True) devolve unknown com o motivo, commit_metrics_reliable = true e sem dominant_share, em vez de classificar com uma heurística que só sabe dizer squash.
  • O relatório ganha um aviso no topo, ao lado do de repositório não-código, em EN e PT-BR. No topo e não na seção de PRs porque essa seção some quando a leitura perdeu todos os PRs. O aviso não promete que uma nova execução resolve: com o gh instalado mas sem autenticação, toda execução falha, e o texto aponta gh auth status.
  • No console, uma leitura que falhou sem trazer PR nenhum aparece como falha, não mais como "pulado (sem remote GitHub ou gh CLI)".
  • docs/METRICS.md §15 documenta o campo, e §28 a regra da merge strategy.

Plano de Teste

  • pytest tests/test_pr_fetch_degradation.py tests/test_merge_strategy_detector.py tests/test_pr_enrichment_caveat.py -v — o campo no payload e a ausência dele num run limpo; unknown sob degradação contra squash com os mesmos dados; os dois pontos de entrada, cli e org_runner, escrevendo o campo num metrics.json real a partir de um repositório git temporário, inclusive nos agregados de adoção; a linha de console de falha; o aviso em EN e PT-BR, inclusive sem seção de PR — rodado em 10441c4: 36 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 10441c4: local: 371 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
  • python scripts/check_analysis_chain.py — nenhum módulo de análise novo — rodado em 10441c4: Analysis chain OK

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

Impacto e Risco

  • Áreas afetadas: agregador, detector de merge strategy, relatório Markdown, textos EN/PT-BR do engine e docs/METRICS.md.
  • Compatibilidade: runs sem degradação geram o mesmo metrics.json e o mesmo relatório. O /api/ingest aceita o campo novo sem alteração (.passthrough(), route.ts:45). Mudança de comportamento deliberada: com o enriquecimento degradado, merge_strategy passa a unknown em vez de um valor enviesado, e o repositório mostra estratégia desconhecida naquele run em vez de squash 100%.
  • Performance: nenhuma mudança.
  • Segurança: nenhuma superfície nova.
  • Acessibilidade e custo AWS: N/A — sem UI e sem infraestrutura.
  • Limitação conhecida: com reviews degradado, as métricas de review ainda saem distorcidas aqui — cobertura 0%, single-pass 100% —, e o aviso diz isso. O fix(engine): omit review-derived metrics when the reviews read fails #284, empilhado sobre este, passa a omiti-las.

Sobre o tamanho (RFC 0028 §2.4): 412 linhas, faixa 251–500. Separar o campo do aviso deixaria o relatório calado sobre algo que o JSON já carrega.

PR empilhado: a base é a branch do #280, então o diff mostra só esta parte. Depois do merge do #280, a base passa a ser a main.

Plano de Rollback

git revert do merge deste PR. O campo some do payload e a merge strategy volta a ser classificada como antes; nada a migrar.

Referências

Autoria Assistida

  • Agente: Claude Code — Claude Haiku 4.5 e Claude Sonnet 5.5 nos commits; Claude Sonnet 5.5 nas revisões por task; Claude Opus 5.5 na orquestração e na revisão final do conjunto
  • Escopo da assistência: a decisão de reportar unknown partiu do autor; desenho e implementação guiada por testes foram assistidos
  • Revisão humana: pendente — o autor revisa antes do merge

🤖 Generated with Claude Code

cpenaforte-clickbus and others added 4 commits October 5, 2026 14:40
The read now knows which steps degraded; this carries that into the
metrics. ReportMetrics gains pr_enrichment_degraded, omitted when nothing
degraded so a clean run's metrics.json is unchanged, and both entry points
pass the read's degradation to aggregate().

Merge strategy changes behavior on purpose. With enrichment degraded, merge
PRs have no parent count and no commit refs and fall through to unknown,
while squash-stamped ones still classify - so the fallback could only ever
answer squash. A mixed repo read as 100% squash with its per-commit metrics
flagged unreliable. The detector now reports unknown, with the reason.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The recent-window and pre/post-adoption metrics are aggregated from slices
of the same PR list, but were not told the read degraded. The adoption
split is written into metrics.json, so a degraded run still carried a
guessed merge strategy there, nested under the top-level unknown. Every
aggregate() over this run's PRs now receives the read's degradation.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The metrics now carry the degradation, but the report still presented
partial PR numbers with the same confidence as complete ones. It states the
failed steps at the top, next to the non-code-repository caveat - not in
the PR section, which a read that lost every PR does not render. English
and Portuguese. docs/METRICS.md documents the field in section 15 and the
merge-strategy rule in section 28.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The caveat promised that a re-run usually recovers the missing PR data,
which is false when gh is installed but not authenticated: then every run
fails the basic step. It also called the affected metrics understated,
but with the reviews step failed, review coverage reads 0% and the
single-pass rate 100% - skewed, not understated. The caveat and the
METRICS.md entry now say so, and point to gh auth status when every run
fails. The console no longer reports a failed read as skipped.

Refs #236

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@cpenaforte-clickbus cpenaforte-clickbus added the type: tech-debt Código sub-ótimo conhecido, workaround, ou cleanup pendente label Oct 5, 2026
@vercel

vercel Bot commented Oct 5, 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 5, 2026 6:23pm UTC

Request Review

@cpenaforte-clickbus cpenaforte-clickbus added the ai-assisted PR gerado total ou parcialmente com auxílio de agente de IA (RFC 0028 §2.2.7) label Oct 5, 2026
@cpenaforte-clickbus cpenaforte-clickbus self-assigned this Oct 5, 2026
@cpenaforte-clickbus
cpenaforte-clickbus marked this pull request as ready for review October 5, 2026 19:16
@clickmatos
clickmatos deleted the branch main October 8, 2026 13:31
@clickmatos clickmatos closed this Oct 8, 2026
@clickmatos clickmatos reopened this Oct 8, 2026
@clickmatos
clickmatos changed the base branch from fix/pr-read-degradation-signal to main October 8, 2026 13:35
@clickmatos
clickmatos merged commit 29d9240 into main Oct 8, 2026
8 checks passed
@clickmatos
clickmatos deleted the fix/pr-read-degradation-report branch October 8, 2026 13:38

This branch was successfully deployed

1 active deployment
Preview — 10441c46 Deployed Oct 5, 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.

2 participants