Pular para conteúdo

AUR-575: o gate falha fechado por construção

Medido antes (auditoria de 2026-10-03, base e6b708fe)

  1. config.Parse validava gate, exceções, analysis_data, ssor_dtrack e supply_chain, mas nunca quality_gates.sast (SastConfig.Validate só era chamado pelos testes): engine: gitleaks rodava o Semgrep calado e um rule_packs com cara de flag passava.
  2. O .aurumcode/config.yml do repositório era lido com yaml.Unmarshal leniente; só a política central fazia um segundo decode com KnownFields(true). gate: {fial_on: [error]} não declarava gate e aprovava.
  3. gate.inconclusive ausente valia "", tratado como warn em todo lugar: SAST habilitado com Semgrep ausente saía 0 com status success (alerta).
  4. Cada fonte decidia sozinha o modo: Dependency-Track e analysis_data calculavam Fail pelo modo, o SAST só marcava Inconclusive, o pipeline tratava o erro de contribuidor à parte, e a falha de artefato também.
  5. sources.go (loop determinístico: catálogo embutido e passe de segurança) e sast.go descartavam com continue uma severidade que SeverityRankOf não reconhecia.

O que mudou

  • internal/config/decode.go: decodeStrict (KnownFields(true), documento vazio = configuração zero) é o decoder de Parse; o decode extra da política em central.go saiu (a mensagem é a mesma: parsing <arquivo>: yaml: unmarshal errors: line N: field X not found in type ...).
  • Parse chama QualityGates.Sast.Validate().
  • internal/config/gate.go: resolveInconclusive(fallback) normaliza o valor; GateConfig.InconclusiveMode() resolve ausente para block quando o gate é declarado. internal/config/inconclusive.go: Config.InconclusiveMode() resolve ausente para block quando há gate ou scanner habilitado (SAST, Dependency-Track, analysis_data); warn só escrito.
  • internal/gate/pipeline.go: ApplyInconclusiveMode é o único ponto que transforma Inconclusive em Fail (modo block, ou modo ilegível); o pipeline aplica após cada contribuidor, e a falha de artefato pós-pipeline reaplica a mesma função. Dependency-Track, analysis_data, artefatos, erro de contribuidor e EvaluateGate só marcam Inconclusive (EvaluateGate ainda lê o modo para não graduar um run bloqueado). aurumcode sbom usa ApplyInconclusiveModeValue com o modo do gate.
  • internal/gate/policy.go: GateRankOf conta severidade desconhecida como error; usado em sast.go e sources.go.
  • Testes que afirmavam o padrão antigo (warn implícito) foram atualizados para o novo contrato; analysisdata_test.go usava a chave inexistente language na raiz (o decode estrito revelou; a chave real é review.language); aur572_test.go escreve inconclusive: warn porque testa a linha final do relatório, não o modo.
  • Tutorial do gate: política politica-sast-padrao (SAST habilitado, sem gate), caso com PATH=/sem-semgrep que sai 1; expected/ e out/ regravados com a imagem do produto; docs configuration.md, gate-corporativo.md e tutorials/gate.md atualizados.

Como cada AC/MUT foi provado

bash tests/acceptance/AUR-575.sh all no container go-shared:

AUR-575/AC-001/pass
AUR-575/AC-002/pass
AUR-575/AC-003/pass
AUR-575/AC-004/pass
AUR-575/AC-005/pass
AUR-575/MUT-001/red: --- FAIL: TestAUR575SastSectionValidatedInParse (0.00s)
AUR-575/MUT-001/pass
AUR-575/MUT-002/red: --- FAIL: TestAUR575SASTMissingBlocksWithoutInconclusive (0.00s)
AUR-575/MUT-002/pass
AUR-575/MUT-003/red: --- FAIL: TestAUR575UnknownSeverityCountsAsError (0.00s)
AUR-575/MUT-003/pass
AUR-575/all/pass
  • AC-001: TestAUR575SastSectionValidatedInParse (chave citada) e TestAUR575InvalidConfigRefusedBeforeModel (runReview --base para na carga, sem relatório).
  • AC-002: TestAUR575UnknownKeyIsRefused (cinco seções, chave e arquivo nomeados) e TestAUR575ExistingConfigsStayValid (percorre todo .aurumcode/config.yml de demo/, docs/, tests/; só os casos de falha deliberados politica-invalida, politica-sem-dono e a fixture legada congelada tests/fixtures/repo1, que já não carregava antes, ficam de fora).
  • AC-003: testes de config, gate e cmd (--base sai ≠ 0; --pr publica failure "revisão inconclusiva (bloqueio)"; warn escrito mantém exit 0 e success com alerta) e o caso do tutorial com run.sh --check.
  • AC-004: TestAUR575OneRuleForEveryInconclusiveSource (erro simples de contribuidor e SAST ausente decidem igual em "", block, warn) e checagem estrutural de que nenhuma fonte de internal/gate calcula Fail pelo modo.
  • AC-005: TestAUR575UnknownSeverityCountsAsError cobre SAST, catálogo embutido e passe de segurança; MUT-003 restaura o continue nos dois sites.

Divergência registrada

O card fala em exit 2 para erro de configuração "como já é na política"; o produto sai 1 em todo erro de carga (política inclusive, ver o caso falha-fonte-invalida do tutorial). Este card manteve o código existente.

Regressão verificada

go vet ./... e go test -p 1 ./... verdes; tests/acceptance/AUR-497.sh, AUR-548.sh, AUR-556.sh, AUR-567.sh, AUR-569.sh, AUR-570.sh all passam; docs/site/index.html não mudou; bash scripts/docs/build.sh com 0 warnings.

v2: AC-006 (todos os tutoriais reexecutados)

Imagem do produto reconstruída desta árvore (AURUMCODE_TUT_REBUILD=1, tag aurum-tutoriais:aur575), run.sh all de todos os 15 tutoriais em série e --check em cada um. Nenhum caso existente mudou de exit code nem de RESULTADO: todos os tutoriais com gate ou scanner que passam por um caminho inconclusivo já escreviam inconclusive explícito. As divergências encontradas eram saída velha do AUR-567 (a linha do gate passou a usar - e a terminar em origem <fonte>, e no SAST origem sast, secao <policy|repo>): expected/ e blocos de docs/tutorials/*.md foram regravados em auditoria-sarif, excecoes, politica-central, qualquer-linguagem, reaproveitamento, sast e skills. Os valores que dependem do relógio ou do board (tag/idade do artefato de dados-de-analise, contagem de cards em operacao) foram regravados com a execução nova. tests/acceptance/AUR-533.sh: MUT-002 reancorada na assinatura atual de ApplyAnalysisDataGate; all verde, as duas provas --pr caem vermelhas sob a mutação. AUR-561..564 all, AUR-533 all e AUR-575 all verdes; scripts/docs/build.sh com 0 warnings.