AUR-451 — O review de pull request passa a usar o motor inteiro
Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.
O defeito medido (revisao de produto 2026-08-14)
cmd/aurumcode/pr.go nunca chamava SecurityScan, e das flags do comando
so usava countAtOrAbove internamente para sustentar --check. No caminho
de pull request -- o caso de uso principal do produto --
--seguranca/--fail-on/--limite/--modelo eram aceitas como flags mas
nao faziam nada: sem varredura de seguranca, sem gate de severidade, sem
teto de custo, sem escolha de modelo. O comentario do proprio pr.go
declarava isso como Non-goal do card que o criou (AUR-438). Este card
remove essa limitacao.
O que este card entrega
aurumcode review --pr <numero> --repo <dono>/<projeto> --publicar --na-linha \
[--seguranca] [--fail-on <nivel>] [--limite <usd>] [--modelo <nome>]
As quatro capacidades que ja funcionavam em --base agora valem em --pr,
reutilizando exatamente as mesmas funcoes que o caminho --base ja
chama (cmd/aurumcode/main.go, cmd/aurumcode/cost.go) -- nenhuma logica
foi duplicada ou reimplementada:
--seguranca: rodareview.SecurityScanWithCoveragesobre o diff do pull request -- o mesmo pacote/funcao que--baseja usa -- e imprime a mesma nota de cobertura do AUR-450 em stderr (security pass applied N of M security rules (...)). Cada achado de seguranca vira seu proprio comentario no pull request, publicado exatamente como um achado de qualidade: na linha exata quando o diff adicionou aquela linha, geral caso contrario (a classificacao do AUR-438,isInlineEligible, que este card nao altera). O comentario carrega a citacao da regra ((rule security/<id>: <titulo>)) porqueMessageja chega assim dereview.enforceRuleCitations-- nao ha uma secao separada como no relatorio stdout de--base, porque o formato de saida de--prsempre foi "um comentario por achado", nao um relatorio de texto.--fail-on <nivel>: apos a publicacao, o comando sai com o mesmo codigo distintoexitFindings(3) que--baseja usa quando algum achado publicado -- de qualidade ou de seguranca -- fica no limiar escolhido ou acima (severityRank/countAtOrAbove, inalterados). E independente do gate proprio de--check(grave-only, AUR-439): qualquer um dos dois fecha o portao sozinho.--limite <usd>: o mesmo gate de custo do AUR-433 (internal/llm/cost.Tracker,buildCostTracker,fixedModelProvider) estima o custo antes de chamar o modelo e recusa -- sem gastar nada -- quando a estimativa excede o teto, reportando a estimativa e, em caso de sucesso, o custo real em stderr. A recusa acontece antes de qualquer comentario ser publicado.--modelo <nome>:selectProviderForModel, o mesmo mecanismo de--base, escolhe o provider; quando o modelo pedido nao pode ser servido,reportModelUnavailablefalha alto (exit 1), nunca um review vazio com exit 0.
Sem nenhuma das quatro flags novas, --pr e byte-identico ao contrato
ja publicado pelo AUR-438/AUR-439 -- provado por sha256 contra um binario
compilado do commit pai (antes deste card), nao so por leitura de codigo
(ver "Prova de compatibilidade" abaixo).
Ordem de validacao
A validacao de --fail-on/--modelo/--limite acontece antes da
checagem de permissao de escrita, da busca do diff e de qualquer chamada
ao modelo -- a mesma ordem que --base ja segue, e pelo mesmo motivo: um
nivel de --fail-on desconhecido, um --modelo vazio ou um --limite
vazio/nao numerico e erro de uso (exit 2), nunca um gate silenciosamente
desabilitado, e nunca vale a pena gastar uma chamada de rede para descobrir
isso.
Onde a seguranca entra na publicacao
runPRReview combina result.Issues (achados de qualidade) com os
achados de seguranca num unico slice antes de sortedIssues -- a mesma
ordenacao (arquivo, linha) que ja rege a sequencia de publicacao do
AUR-438. Um achado de qualidade e um achado de seguranca na mesma linha
publicam dois comentarios distintos, nenhum e descartado nem mesclado no
outro.
Ordem de prioridade se o escopo precisasse ser cortado
O card declarou esta ordem de valor; todas as quatro foram entregues, mas fica registrada porque orientou o desenho:
--segurancacom--pr(o caso de uso que vende o produto).--fail-oncom--pr(o gate de CI passa a considerar severidade).--limitecom--pr(nao gastar sem teto no caminho automatico).--modelocom--pr.
Prova de compatibilidade (sha256 contra o binario do commit pai)
Como parte da validacao deste card, o binario atual (cmd/aurumcode com
este card integrado) e o binario compilado do commit pai
(git show HEAD:cmd/aurumcode/{main,pr}.go, antes deste card) foram
executados com o comando review --pr 42 --repo dono/projeto --publicar
--na-linha -- sem nenhuma das quatro flags novas -- contra o mesmo fake
GitHub e a mesma resposta de modelo deterministica. stdout e stderr sao
byte a byte identicos entre os dois binarios (mesmo sha256), confirmando
que o comando publicado antes deste card nao mudou nenhum byte.
Exit codes
Inalterados: o mesmo vocabulario que --base e --pr ja publicavam.
0: os achados foram publicados (ou "No issues found."), sem erro, e (quando--fail-onfoi dado) nenhum achado publicado atingiu o limiar.1: falha em tempo de execucao -- busca do diff, chamada ao modelo, recusa por falta de permissao de escrita, falha ao publicar um comentario especifico,--modeloindisponivel, ou--limiteestourado (nada foi gasto).2: erro de uso -- inclui agora um--fail-ondesconhecido, um--modelovazio, ou um--limitevazio/nao numerico/nao positivo em--pr, exatamente como--baseja recusa.3(exitFindings): pelo menos um achado publicado -- de qualidade ou de seguranca -- ficou no limiar de--fail-onou acima. Novo neste card para o caminho de PR; o mesmo codigo que--checke--baseja usam para o mesmo significado.
Exemplo executavel sem segredo
bash tests/e2e/AUR-451.sh E2EAUR451
Compila o binario real, sobe um fake GitHub em loopback a partir de
tests/fixtures/scm/github/ (permissoes de leitura-escrita e so-leitura,
resposta de comentario criado) servindo um diff que este script constroi --
tests/fixtures/scm/github/pr-42.diff e um read_path, nao editavel por
este card, e nao contem nada que uma regra de seguranca do catalogo
combine -- plantando API_KEY=AURUM-FAKE-KEY-9000-2222 (o mesmo valor
sintetico que tests/unit/AUR-442.go ja prova bater com
security/hardcoded-secret) na linha adicionada de cmdb/settings.go.
Roda aurumcode review --pr 42 --repo dono/projeto --publicar --na-linha
--seguranca --fail-on high contra ele. Prova: o achado plantado chega como
comentario inline citando security/hardcoded-secret; o comando sai com
3; repetir a execucao produz a mesma saida; --seguranca sozinho (sem
--fail-on) ainda publica o achado mas sai com 0; sem nenhuma flag nova
o mesmo diff nao publica nada (No issues found., prova de que a correcao
e aditiva); --limite 0.0001 recusa antes de qualquer publicacao;
--modelo local sem provider configurado falha alto; um token so-leitura
continua recusado antes de qualquer busca ou publicacao.
Selectors e exit codes do aceite
- Aceite:
tests/acceptance/AUR-451.sh-- selectorsAC-001(tudo),TestAUR451,IntegrationAUR451,E2EAUR451,AC-001-MUT-001. - Exit codes (convencao do board,
tests/acceptance/EXIT_CODE_CONVENTION.md):0comportamento provado;1RED comportamental;64selector desconhecido;79infraestrutura / inconclusivo (nunca evidencia de RED).
Nota de nomenclatura de selector (a mesma tecnica que tests/unit/AUR-442.go,
tests/unit/AUR-449.go e tests/unit/AUR-450.go ja documentam): o texto do
card nomeia TestAUR435/IntegrationAUR435/E2EAUR435 na secao TDD proof,
um artefato de copia-e-cola do card AUR-435 usado como base de redacao.
Esses simbolos ja existem em seus pacotes
(tests/unit/AUR-435.go, tests/integration/AUR-435.go), entao as provas
deste card sao TestAUR451/IntegrationAUR451/E2EAUR451.
MUT-001
Mutacao: em uma copia gravavel de cmd/aurumcode/pr.go, a linha
result.Issues = combined -- o unico ponto onde os achados de seguranca
entram na lista publicada como comentarios -- e substituida por um
no-op. --seguranca continua sendo aceita e validada como flag, a nota de
cobertura do AUR-450 continua imprimindo em stderr, mas nenhum achado de
seguranca chega a virar comentario: exatamente o defeito medido que este
card corrige. Sob a mutacao, o cenario AC-001 (--seguranca --fail-on
high sobre o diff com o segredo plantado) nao encontra nenhum achado a
publicar, cai no ramo pre-existente "No issues found." e sai com 0 em
vez de 3 -- tests/e2e/AUR-451.sh rejeita isso
(ac001_wrong_exit/ac001_missing_finding_line/etc.). A fonte
versionada nunca e tocada; a restauracao roda a mesma prova contra o
binario nao mutado e reproduz o GREEN exato.
Diagnostico de falha
AUR-451/AC-001/behavior-missing: o caminho de PR nao entrega nenhuma das quatro capacidades.ac001_missing_finding_line/ac001_missing_rule_citation/ac001_missing_inline_marker/ac001_wrong_post_count: o achado de seguranca plantado nao foi publicado -- o defeito medido, ou uma regressao equivalente.ac001_wrong_exit: o gate--fail-onnao fechou sobre o achado grave de seguranca (ou fechou quando nao devia).limite_missing_refusal/limite_post_leaked:--limitenao recusou antes de publicar, ou recusou tarde demais (algo ja tinha sido postado).modelo_missing_message:--modeloindisponivel nao falhou com a mensagem esperada dereportModelUnavailable.readonly_not_refused/readonly_post_leaked: a recusa de publicacao sem permissao de escrita (AUR-437/AUR-438, inalterada por este card) foi violada.non_deterministic: duas execucoes identicas divergiram.infrastructure/missing_go,infrastructure/mktemp,infrastructure/fakegithub_did_not_start(exit 79): ambiente, nunca RED.
Compatibility, migration, rollback
- Compatibility: sem as quatro flags novas,
--pr ... --publicar --na-linhae byte-identico ao contrato ja publicado pelo AUR-438/ AUR-439 (ver "Prova de compatibilidade" acima); os exit codes existentes (0,1,2) mantem seu significado, e3so aparece quando--fail-one explicitamente dado.--check(AUR-439) continua com seu proprio gate grave-only, agora composto -- nao substituido -- pelo gate de--fail-on.--seguranca,--fail-on,--limitee--modelono caminho--basenao sao tocados por este card. - Migration: not-applicable.
- Rollback: reverter somente os
pathsdeste card; nenhum estado externo e publicado por ele fora do que o proprio usuario pediu ao rodar o comando.