AUR-619 — Publicação sem permissão nomeia a permissão que falta; QA do consumidor aprova a correção de ponta a ponta
Problema
No QA do consumidor (cenário sem-permissao, token só de leitura), o produto
imprimia publishing review summary: HTTP 403: {"message":"Resource not
accessible by integration", ...} três vezes e 1 comentario(s) falharam ao
publicar, sem dizer que faltava permissão nem qual. O verificador do QA
exige que o diagnóstico diga que faltou permissão, e reprovava.
No cenário comments-inline, a rodada corrigida concluía failure embora
aurumcode/policy-gate e aurumcode/review tivessem aprovado: a fixture da
correção não trazia entrada de changelog e o job changelog / Changelog
obrigatório do consumidor reprovava a PR. O verificador só dizia
conclusão "failure", esperada "success", sem nomear o check culpado.
Desenho
| arquivo | responsabilidade |
|---|---|
internal/git/githubclient/apierror.go |
APIError{Status, Body}: toda resposta fora da faixa de sucesso vira dado, com o mesmo texto HTTP <status>: <corpo> de antes; PermissionDenied (401 ou 403) e IsPermissionDenied(err) por errors.As. |
internal/git/githubclient/client.go |
Os nove pontos que montavam fmt.Errorf("HTTP %d: %s") devolvem apiError; o diff grande continua com ErrDiffTooLarge encadeado (%w: %w). |
cmd/aurumcode/publish_permission.go |
publishAction (publishComment → pull-requests: write; publishStatus → statuses: write) e publishError(language, action, err): recusa por permissão vira o texto do catálogo terminal.publish_denied com a permissão, onde declará-la e a resposta do GitHub; qualquer outro erro mantém o texto. |
cmd/aurumcode/review_pr_publish.go, pr.go, policygate.go |
Revisão formal, comentário na linha, parecer, sugestão aplicável, status aurumcode/review e aurumcode/policy-gate imprimem publishError; a lista final de falhas leva o mesmo texto. Exit codes inalterados. |
internal/i18n/catalog.yml |
terminal.publish_denied em pt-BR e en (%s permissão, %v resposta). |
tests/consumer/consumer.go |
failedChecks: quando a conclusão difere da esperada, o motivo lista os checks que não passaram (success, skipped e neutral não contam). |
tests/consumer/fixtures/bug-sql-corrigido/CHANGELOG.md |
A correção do SQL traz a entrada em ## Unreleased, no molde de changelog-entrada, para o changelog obrigatório do consumidor aprovar a PR corrigida. |
docs/configuration.md |
Seção "Permissões do token e o que o log diz quando falta": tabela publicação → permissão, onde declarar, exemplo do diagnóstico. |
O produto não publica check runs, então checks: write não entra no
mapeamento: só o que o código escreve aparece na tabela.
Provas
tests/acceptance/AUR-619.sh (cópia de go.mod go.sum cmd internal pkg
tests/consumer):
| id | prova | última linha |
|---|---|---|
| AC-001 | TestAUR619PermissionDeniedNamesThePermission (pt-BR e en, 401 e 403, outros erros intactos), TestAUR619PublishingDeniedReachesTheOperator (GitHub falso que recusa todo POST/PATCH com a resposta real do token de workflow: comentário na linha, parecer, status da revisão e do gate nomeiam a permissão, mantêm o HTTP 403, exit de falha), TestAUR619APIErrorKeepsTheHTTPLine, TestAUR619PermissionDeniedStatuses, TestEveryKeyExistsInEveryLocale |
AUR-619/AC-001/pass |
| AC-002 | TestAUR619PublishingDeniedReachesTheOperator (linhas de status), TestAUR619ClientAnswersAreTyped (todo write do cliente devolve o erro tipado; 422 não é recusa por permissão) |
AUR-619/AC-002/pass |
| AC-003 | TestAUR619CorrectionFixtureCarriesAChangelogEntry, TestAUR619FailedChecksAreNamed |
AUR-619/AC-003/pass |
| MUT-001 | publishError devolve o erro cru para toda recusa: AC-001 cai por asserção (o teste roda e falha, não é falha de build) |
AUR-619/MUT-001/killed |
| MUT-002 | fixture da correção sem a entrada de changelog: AC-003 cai | AUR-619/MUT-002/killed |
Prova selada: ./.board/bin/oci-run --profile go-unit-offline-v1 --card AUR-619.
Limites
Quando nada pode ser publicado, o parecer não é reimpresso no log por outro
caminho (non-goal do card); o exit de falha e o diagnóstico são a resposta.
O cenário sem-permissao só passa no QA do consumidor numa rodada com o
AurumCode deste commit ou posterior; a evidência do candidato anterior
continua reprovando, agora dizendo qual check reprovou no comments-inline.