AUR-595: a autorrevisão conclui em PR real
Medido antes (base 7b9cb359, PR #89)
A autorrevisão da PR #89 (configuração do próprio repositório, AUR-591)
terminou inconclusiva por três motivos. Auditoria do job
(aurumcode-audit-89): deliberation.rounds=1, tokens_in=65918,
tokens_out=91, desfecho deliberation_limit:max_cost_tokens; gate
fail com SECRETS (gitleaks, ...) inconclusivo (secrets_execution_error)
e dois security/command-injection em
demo/tutoriais/sast/out/nosemgrep-e-semgrepignore.log:36 e
demo/tutoriais/sast/out/regra-local.log:22.
- Teto de deliberação contava o prompt base.
Session.Run(internal/deliberation/session.go) somavaTokensIn + TokensOutde todas as rodadas e comparava commax_cost_tokens(60000). A primeira rodada já carrega o prompt base inteiro (65918 tokens numa PR média): o teto estourava antes de o modelo pedir qualquer ferramenta. - Gitleaks no merge commit. Diagnóstico reproduzindo o job: clone com o
mesmo fetch do
actions/checkout(fetch-depth: 0:+refs/heads/*:refs/remotes/origin/*e tags), checkout destacado da cabeça da PR, montado só leitura num container root comsafe.directoryviaGIT_CONFIG_*, e os mesmos comandos deverifyRange/scanRange:
== GITHUB_SHA=a1ee8f28... (refs/pull/89/merge)
cat-file 098f7342... rc=0
fatal: Not a valid object name a1ee8f28...^{commit}
cat-file a1ee8f28... rc=128 -> ErrBadRange -> secrets_execution_error
== GITHUB_SHA=110ffb72... (cabeça da PR)
cat-file 110ffb72... rc=0
gitleaks rc=0 INF 12 commits scanned. WRN leaks found: 2
O env: do passo define GITHUB_SHA com a cabeça, mas num evento
pull_request o GitHub reserva a variável ao merge commit sintético
(o mesmo fato de AUR-504; o workflow_sha da auditoria é o merge
a1ee8f28). O checkout da cabeça não traz refs/pull/N/merge, então a
ponta do intervalo não existia no clone. O motivo publicado era só o
token, sem dizer qual ponta faltava.
3. Logs gravados de tutorial na revisão. demo/tutoriais/*/out/*.log
repetem de propósito exemplos com eval(); o passe de segurança os
acusou como código adicionado.
O que mudou
internal/deliberation/transcript.go,session.go: o transcript registrabase_tokens(entrada da primeira rodada, o prompt base como o provedor o mede) ecost_tokens(saída de cada rodada + o que a entrada de cada rodada seguinte traz além do prompt base).max_cost_tokenslimitacost_tokens; o prompt base segue sob o orçamento do prompt. O detalhe do limite diz os dois números.cmd/aurumcode/pr_scan_range.go,review_pr_analysis.go: no--pro intervalo dos scanners éAURUMCODE_BASE_SHA..HEAD do checkout verificado(oHEADqueresolveCheckoutjá provou igual à cabeça da API); nuncaGITHUB_SHA. Sem checkout verificado a cabeça fica vazia e os scanners continuam bloqueados (*_unverified_checkout).internal/scanner/detail.go,executor.go:Outcome.Erré o erro cru da engine, nunca publicado como está;Summarize(err, redact)redige o texto cru inteiro (com as quebras de linha) e só depois colapsa espaços e corta em 240 bytes na fronteira de rune. Sem redator, não há detalhe. Ordem medida pela revisão: resumir antes de redigir vazava o prefixo de umghp_cortado no limite e umAuthorization: Bearerem linha própria (o padrão é ancorado no começo da linha); o gitleaks também não corta mais a linha citada de stderr e a põe em linha própria.internal/gate/scanner.go:Scan.Detail; a linha do gate ficainconclusivo (<token>) [detalhe: ...](o token continua inteiro entre parênteses).cmd/aurumcode/scanner_pass.go: o detalhe passa pelo filtro de redação da revisão antes de qualquer saída e entra na limitação publicada (notice.scanner_detail,internal/i18n/catalog.yml).internal/scanner/gitleaks/invocation.go: os erros dizem qual ponta (base commit <id> not found in the checkout), clone raso, e a última linha de stderr dogit/gitleaksque falhou (ou a primeira linhaERR/FTLde um log com erro e exit 0)..aurumcode/config.yml:ignoreganhademo/tutoriais/*/out/**edemo/tutoriais/*/expected/**.docs/configuration.md: teto relativo, intervalo do--pr, detalhe do motivo, recomendação para artefatos gerados.docs/getting-started.md: as três notas.
Provas
bash tests/acceptance/AUR-595.sh all (go-shared, GOCACHE do chamador; o
mesmo no selado oci-run --profile go-unit-offline-v1 --card AUR-595):
AUR-595/AC-001/pass
AUR-595/AC-002/pass
AUR-595/AC-003/pass
AUR-595/AC-004/pass
cost_test.go:18: a base prompt above the ceiling stopped a deliberation that asked for nothing: deliberation_limit: max_cost_tokens (66009 tokens de deliberacao alem do prompt base de 65918, teto 60000)
--- FAIL: TestAUR595LargeBasePromptWithoutToolsIsNotALimit (0.00s)
aur595_test.go:252: exit=1 deliberation=&{Outcome:deliberation_limit:max_cost_tokens BaseTokens:4347 CostTokens:4396}, want an answered deliberation; ...
--- FAIL: TestAUR595BasePromptAboveTheCeilingConcludes (0.09s)
AUR-595/MUT-001/rejected
aur595_test.go:185: gitleaks never scanned (exit=1)
--- FAIL: TestAUR595GitleaksScansThePullRequestHeadNotTheMergeCommit (0.06s)
AUR-595/MUT-002/rejected
AUR-595/all/pass
- AC-001:
TestAUR595LargeBasePromptWithoutToolsIsNotALimit(base 65918, teto 60000, sem ferramenta: responde,cost_tokens=91),TestAUR595ToolRoundsBeyondTheBaseStillExceedTheCeiling(rodadas de ferramenta somam 13314 além da base, teto 8000:max_cost_tokensna rodada 3),TestAUR580MaxCostTokensIsALimitError(reescrito para estourar por rodada de ferramenta),TestAUR595BasePromptAboveTheCeilingConcludes(ponta a ponta: base 4347 > teto 300, conclui, auditoria combase_tokens/cost_tokens) eTestAUR580CostExceededIsInconclusive. - AC-002:
TestAUR595GitleaksScansThePullRequestHeadNotTheMergeCommit(checkout com objetos git soltos, sem binário git, que o perfil selado não tem; o executor de teste respondecat-file/rev-parsepelo object store do próprio checkout, entãoverifyRangedecide sobre o repositório real;GITHUB_SHA= merge ausente: o gitleaks recebebase..heade o gate conclui; o mesmo caminho com o git e o gitleaks de verdade está na reprodução da PR #89 abaixo);TestAUR595AbsentBaseIsInconclusiveWithItsDetail(base ausente seguesecrets_execution_error). - AC-003:
TestAUR595AbsentBaseIsInconclusiveWithItsDetail(o detalhebase commit <id> not found in the checkoutna linha do gate, nogate.reasonda auditoria e no parecer publicado) eTestAUR595EngineFailureDetailIsRedacted(uma credencial impressa pela engine sai[REDACTED]no stderr, na auditoria e no parecer). - MUT-003: juntar e cortar antes de redigir -> AC-003 vermelho
(
TestAUR595SummaryRedactsATokenAtTheCutmostraghp_Q7w...,TestAUR595SummaryRedactsAHeaderOnItsOwnLineeTestAUR595EngineHeaderLineIsRedactedmostram o valor do header). - MUT-001: somar a entrada da primeira rodada em
CostTokens-> AC-001 vermelho (unitário e ponta a ponta). MUT-002:r.Head = p.env().githubSHA-> AC-002 vermelho (o gitleaks nunca roda; o intervalo aponta para o merge ausente).
Reprodução real com a PR #89 (cabeça d25edc75, merge 4f14aec1 ausente
do clone, base 098f7342), aurumcode review --pr 89 --publicar --check
contra um proxy local só leitura da API (escritas descartadas localmente):
imagem de main (7b9cb359): SECRETS (gitleaks, origem gitleaks, secao repo) inconclusivo (secrets_execution_error)
imagem desta branch: gitleaks:generic-api-key ... in commit 3b77f2c4792c (gitleaks v8.30.1) (severidade error, ...)
gitleaks:aws-access-token ... in commit 2dd5caf978f4 (gitleaks v8.30.1) (severidade error, ...)
A varredura conclui; os dois achados são canários de teste da própria PR #89
(cmd/aurumcode/mcp_server_test.go:18, internal/mcpserver/server_test.go:197),
que passam a contar no gate dela.
AC-004: como verificar na PR deste card
O --pr lê do branch base as configurações que afetam o gate (regras,
ignore): a PR não enfraquece a própria revisão. Logo o ignore novo de
.aurumcode/config.yml só vale para as PRs abertas depois de este card estar
no main; o código (teto relativo, intervalo, detalhe) vale já, porque o
workflow roda a ferramenta do merge da PR (job.workflow_sha).
- Abrir a PR de
card/AUR-595paramain. - O check
review / Review pull requestprecisa terminar verde, com oaurumcode/policy-gateem success. Na auditoria (aurumcode-audit-<N>):deliberation.outcomediferente dedeliberation_limit:*,deliberation.base_tokensecost_tokenspresentes, nenhumsecrets_execution_erroremgate.reason. - Se o passe de segurança acusar
demo/tutoriais/*/out/*.logouexpected/*.txtregravados por este card (oignoreainda é o domain), não é regra a desligar: o hunk de.aurumcode/config.ymlentra nomainprimeiro e a PR é reavaliada por um novo evento (git merge main+ push), que relê a configuração da nova base.
Fora do escopo
Desligar regra, aumentar tetos, tratar falha de scanner como sucesso. Os achados do gitleaks na PR #89 são dela.