Pular para conteúdo

AUR-538: provas que faltaram no gate do AUR-519

Fecha oito lacunas de prova não bloqueantes deixadas pelas revisões do AUR-519/520, sem mudar o comportamento do gate (ver Non-goals do card).

AC-001 — veredito nunca lê Approve sob bloqueio

Com --base, uma fixture sem nenhum achado (nenhum segredo fixo no código) e gate: inconclusive: block, o relatório local nunca mostra **Verdict:** Approve, para veredito do modelo "" ou "changes_requested". O mecanismo real é a marca result.Metadata[prompt.PolicyGateWithheldKey] = "true" (main.go), lida por formalReviewEvent/canonicalVerdict (pr.go/passes.go) — nunca o campo result.Verdict que o modelo controla. Um controle positivo prova que a mesma fixture, sem gate, publica Approve normalmente: a ausência de "Approve" sob bloqueio só pode ser explicada pela marca, nunca por uma propriedade incidental da fixture (ver AC-003).

AC-002 — a marca retida não pode ser forjada

O parser (internal/prompt/parser.go) descarta metadata.policy_gate_withheld de toda resposta do modelo, antes de qualquer leitura própria do motor — um modelo nunca escreve essa marca.

AC-003 — assertiva decorativa corrigida

TestAUR519GatePartialCoverageInconclusiveWarns usava coverageFixture (AUR-476), cujo app.go sempre embute um segredo fixo para um propósito não relacionado. Passou a usar aur538CleanFixture, sem nenhum conteúdo que pareça segredo, para que a assertiva só possa ser explicada pelo rebaixamento do veredito do próprio gate.

AC-004 — árvore do HEAD ilegível é inverificável

Sem binário git, um checkout com metadados git reais mas cujo objeto da árvore do HEAD foi apagado (perfil selado: apenas objetos soltos) é declarado codebaseContextReasonUnverifiable — nunca limpo — tanto com quanto sem git no PATH. Testado chamando verifiedCleanCheckoutReason diretamente, isolando exatamente o erro de TrackedFiles.

AC-005 — identidade do repositório indisponível

Com --base e sem remoto origin configurado, uma exceção que corresponderia exatamente ao achado falha fechada (o gate reprova e o aviso de identidade indisponível aparece). Sem nenhuma exceção configurada, o aviso não aparece.

AC-006 — exceção ativa vence a vencida

matchException (aur520.go) agora prefere o primeiro match ATIVO, independente da ordem na lista — uma renovação (entrada vencida mantida para histórico, seguida de uma nova com validade futura) aplica a renovada.

AC-007 — descrição do status respeita o limite do GitHub

A descrição do commit status aurumcode/policy-gate é limitada a 140 caracteres (limite do GitHub), contados por rune (nunca por byte, para não corromper um caractere acentuado), sempre com o resultado primeiro (falha/inconclusivo/aprovado) e, quando truncada, terminando em uma única elipse. Dentro desse corte, orderedGateReasons ordena em três níveis — achado real primeiro, linha de exceção aceita/vencida depois, motivo de inconclusividade por último — para que nem uma linha de exceção longa nem o motivo de inconclusividade (já nomeado pela palavra e pelo state do próprio status) possam empurrar um achado real para fora do limite. Uma tabela de teste cobre as cinco combinações de gateDecision (reprova+inconclusivo, reprova, bloqueio inconclusivo sem reprova, alerta inconclusivo sem reprova, limpo), conferindo state E a palavra-resultado juntos. O corpo completo do review nunca é afetado — só este campo publicado.

Revisão independente (69a5e39 → este commit)

  • result.Verdict = "comment" era morto para a renderização (main.go e pr.go): renderPass/localVerdict já substituem result.Verdict por canonicalVerdict(result) antes de qualquer leitura por render.Summary, e formalReviewEvent/reviewVerdictForLanguage nunca leem result.Verdict. As duas atribuições mortas foram removidas e o comentário que afirmava o contrário (dizendo que render.Summary lia result.Verdict diretamente) foi corrigido — a marca PolicyGateWithheldKey é o único mecanismo.
  • O comentário de TestAUR519GatePartialCoverageInconclusiveWarns dizia que o segredo fixo da fixture antiga não mascarava o resultado; estava errado — mergeStaticAnalysis roda sem precisar de --seguranca e alimenta result.Issues diretamente, então o achado determinístico por si só já mantinha o veredito fora de "approve", mascarando o próprio mecanismo que o teste deveria provar. Corrigido.
  • AC-008 do tests/acceptance/AUR-538.sh ganhou um controle negativo: ele copia o AUR-520.sh (e a árvore que ele precisa) para um diretório próprio, remove um dos dois testes nomeados do test_pattern de cada seletor de AC (mantendo names intacto) e exige saída 1 com missing-pass:<nome removido> no stderr — provando que o laço de AC-008 é quem detecta a regressão, não apenas "o script saiu 0".

AC-008 — seletores do AUR-520.sh exigem seus próprios testes

Cada seletor de AC em tests/acceptance/AUR-520.sh (não só all) agora confere que TODOS os seus próprios testes nomeados aparecem com --- PASS: no log — nunca apenas "algum teste passou".

Testes e aceite

Comportamento em cmd/aurumcode/aur538_test.go, cmd/aurumcode/aur519_e2e_test.go (AC-003) e internal/prompt/parser_aur538_test.go. tests/acceptance/AUR-538.sh roda os seletores all, AC-001..AC-008 e AC-001-MUT-001 (remove a marca de veredito retido em main.go; AC-001 deve ficar RED).

Rollback

Limitado aos paths do card: cmd/aurumcode, internal/prompt, tests/acceptance/AUR-520.sh, tests/acceptance/AUR-538.sh, docs/specs/AUR-538.md.