Pular para conteúdo

AUR-545: achado com evidencia fora das linhas alteradas tem destino definido

O que foi medido antes

  • internal/review/scope.go (filterModelIssues) checava o escopo antes de qualquer prova: todo achado do modelo fora das linhas adicionadas ou removidas era descartado e contado em OutsideAddedLines (issues_rejected_by_scope, scope_discard_warning), mesmo com evidencia, impacto e verificacao completos.
  • Consequencia: o comentario geral de PR prometido pelo AUR-438 era inalcancavel para achados do modelo. bash tests/e2e/AUR-438.sh no container terminava com AUR-438/AC-001/missing_general_finding (exit 1), e tests/acceptance/AUR-542.sh fixava esse vermelho em red_scripts.
  • scope_test.go fixava o comportamento oposto ao AUR-438: um achado em other.go e os casos "wrong coordinate space", "unrelated file" etc. so podiam ser "nao mantidos", sem distinguir descarte de destino geral.
  • O gate da politica le apenas Review.Issues mais Extra (internal/gate, IssuesForGate); --fail-on, o veredito, o status --check, o SARIF e a auditoria derivam da mesma lista.

Decisao

Um achado do modelo fora das linhas alteradas que traz a prova completa (evidencia, impacto e verificacao nao vazios), um caminho relativo valido e uma regra do catalogo citada vira comentario geral: nunca inline, nunca entra em result.Issues, logo nunca conta para o gate da politica, nunca conta para --fail-on, nunca muda o veredito para reprovar, nunca entra no SARIF nem na auditoria. Achado fora do diff sem essa prova continua descartado e contado em issues_rejected_by_scope / scope_discard_warning, com o mesmo texto de antes. Um comentario geral fora do diff nunca conta para o gate.

Motivo

  • O modelo le contexto do repositorio de proposito; um defeito real em codigo nao tocado mas afetado pela mudanca (um chamador que quebra) e informacao util ao revisor humano. Descartar com prova completa perdia essa informacao sem ganho de precisao.
  • O risco que o filtro de escopo existe para evitar e o achado ganhar autoridade sobre codigo nao tocado. Essa autoridade so existe quando o achado conta para o gate, o veredito ou e ancorado na linha. Como o achado geral fica fora de result.Issues, ele nao tem nenhuma das tres.
  • O requisito de evidencia nao foi afrouxado: a prova exigida e a mesma do achado inline, a citacao de regra passa pelo mesmo gate de regras (rejeicao soma em issues_rejected_without_rule), e o filtro do marcador de redacao (AUR-598) continua rodando antes do escopo.

O que mudou

  • internal/review/scope.go: filterModelIssues devolve kept, outside e o resumo de descarte; so roteia para outside com prova completa e caminho normalizado valido.
  • internal/review/outside_diff.go: canal outside_diff_findings (chave de metadado do motor, JSON de types.ReviewIssue), OutsideDiffFindings para os consumidores. O motor sempre reescreve ou remove a chave depois dos gates, entao um valor forjado na resposta do modelo nao sobrevive.
  • internal/review/reviewer.go: applyGates separa o canal e passa os achados gerais pelo gate de regras (citedOutsideDiff); annotateResult grava o canal.
  • internal/review/batch_merge.go: lotes concatenam o canal.
  • cmd/aurumcode/outside_diff_output.go: --pr publica cada achado geral como comentario de PR (corpo com arquivo:linha), nos modos separado e review; --base lista o achado com o marcador -- fora das linhas alteradas (comentario geral; nao conta para o gate).
  • tests/e2e/AUR-438.sh: fixture ganha um terceiro achado fora do diff sem evidencia que nunca pode ser publicado; contagens de POST atualizadas para o comentario de resumo (que o produto passou a publicar depois que o script foi escrito) e ordem de publicacao checada entre execucoes.
  • tests/acceptance/AUR-542.sh: AUR-438 saiu de red_scripts para fixed_scripts; nao resta script "vermelho esperado".

Limitacao conhecida: o cache de revisao por arquivo guarda apenas result.Issues; num acerto de cache o comentario geral nao e republicado (comportamento conservador: nunca adiciona achado que conte).

Como cada AC/MUT foi provado

tests/acceptance/AUR-545.sh (selectors all, AC-001, AC-002, AC-003, MUT-001; seletor desconhecido sai 64):

  • AC-001: esta spec tem Decisao e Motivo; scope_test.go (TestFilterModelIssuesRoutesProvedOutsideFindingsAndRejectsUnproved, TestDeletionRegressionUsesOldSideWithoutAdmittingUntouchedCode) e tests/e2e/AUR-438.sh (AUR-438/AC-001/E2EAUR438/ok) passam.
  • AC-002: TestOutsideDiffAC002UnprovedFindingStillDiscarded (issues_rejected_by_scope=1, warning presente), TestFilterModelIssuesNeverRoutesOutsideFindingWithoutFullProof e a checagem unproved_outside_finding_published do e2e.
  • AC-003: TestOutsideDiffAC003ProvedFindingNeverCountsForTheGate (o motor nunca poe o achado em result.Issues) e TestOutsideDiffFindingNeverCountsForTheGate (cmd/aurumcode): a sessao --pr real, contra um GitHub falso em processo, com um achado error provado em app.go:1 (linha nao alterada) e --fail-on error, sai 0, publica o achado como comentario geral com app.go:1 no corpo, nunca inline, e o parecer fica **Verdict:** Approve. (O selado nao tem git, por isso a prova usa o caminho --pr, nao --base.)
  • MUT-001: a mutacao result.Issues = append(result.Issues, outcome.outsideDiff...) faz o teste do motor falhar ("a finding outside the diff reached result.Issues") e a sessao --pr sair 3 sob --fail-on error.

Ultimas linhas reais (container go-shared):

MUT-001 red: an outside-diff finding counted for the gate: exit=3
AUR-545/all/pass