Pular para conteúdo

AUR-472 — Ref de action validada contra tags que existem, nao contra um formato

Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.

O achado

internal/documentation/welcome/sanitize.go tratava qualquer ref com FORMA de tag semver (v2, v10, v1.99) como se ja fosse a tag publicada, sem conferir se ela existe de verdade. So existiam v1, v1.0.0 e v1.0.1, entao nao era explorável no estado anterior -- mas um branch v2 aberto para a proxima major (pratica comum) passaria sem reescrita e sem aviso, publicando exatamente o anti-padrao de branch mutavel que o AUR-465 existe para matar. E o mesmo erro de forma-versus-valor que ja apareceu duas vezes no mesmo dia como strings.Contains num portao (AUR-457, AUR-465).

O conserto

SanitizeActionRefTags(content string, tags []string) TagSanitizeResult e a nova funcao dona da decisao: um ref so passa quando e um SHA completo de 40 hex (o pin mais estrito, sempre aceito) ou uma correspondencia EXATA contra tags, o conjunto de tags que realmente existem. pinnedTagPattern (a checagem de forma) deixou de decidir conformidade -- fica declarada apenas porque tests/e2e/AUR-465.sh referencia o simbolo pelo nome na sua propria mutacao MUT-001.

publishedTags (v1, v1.0.0, v1.0.1) e a lista declarada -- um literal Go dentro do proprio sanitize.go, nao uma consulta ao binario git (que a imagem selada nao tem) nem a rede (Non-goal do card). PublishedTags() expoe uma copia dessa lista para quem precisar dela (o proprio Generator.Generate).

Quando tags esta vazia ("sem lista disponivel"), o comportamento seguro do Non-goal se aplica: toda ref que nao seja SHA completo e reescrita para a tag de major publicada, e a reescrita e anunciada dizendo explicitamente que nao havia lista para validar contra.

SanitizeActionRef(content string) (string, bool) continua existindo com a mesma assinatura de duas saidas -- o AUR-465 depende dela -- e delega para SanitizeActionRefTags(content, publishedTags).

Generator.Generate (internal/documentation/welcome/generator.go) chama SanitizeActionRefTags(resp.Text, PublishedTags()) e registra cada Notices[i] via log.Printf("[Welcome] %s", notice) -- a reescrita e anunciada no ponto de entrada real que cmd/regenerate-docs usa, nao so no retorno da funcao.

Non-goals cumpridos

  • Nenhuma consulta a rede: a lista e um literal Go declarado neste arquivo.
  • Nenhuma dependencia do binario git: a imagem selada nao tem git, e o sandbox materializa por git ls-files -- .git nunca chega la, e forbidden_paths ja o proibe.
  • SHA completo nunca e rejeitado, com ou sem lista disponivel.
  • Sem lista disponivel, a geracao nao trava: toda ref nao-SHA e reescrita para a tag de major, e o motivo e anunciado.

Validacao deste card

  • Unit: tests/unit/AUR-472.go::TestAUR472 -- v2/v10/v1.99 (forma valida, tag inexistente) reescritos e anunciados; v1/v1.0.0/v1.0.1 (tags reais) intocados; SHA completo intocado com e sem lista; sem lista, ate um v1 (que seria real) e reescrito, e o aviso diz que nao havia lista; SanitizeActionRef (compatibilidade) reproduz o mesmo resultado que SanitizeActionRefTags(content, PublishedTags()).
  • Integration: tests/integration/AUR-472.go::IntegrationAUR472 -- chama Generator.Generate de ponta a ponta com um llm.Provider mock cuja resposta reproduz o defeito medido (@v2), prova que a saida real do entrypoint que cmd/regenerate-docs usa ja sai reescrita para v1; uma segunda chamada com @v1 prova que uma tag real sobrevive intocada.
  • E2E: tests/e2e/AUR-472.sh::E2EAUR472 -- compila e executa um binario Go standalone (nao go test) contra uma copia de modulo que carrega somente sanitize.go, provando que o guardrail funciona sozinho e que a lista de tags viaja com o arquivo, sem git nem internal/llm.
  • Accept: ./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-472.

Mutantes

  • MUT-001 (AC-001): reinstalar a checagem antiga baseada em pinnedTagPattern numa copia de scratch faz a lane unit e a lane e2e reprovarem, ambas reportando AUR-472/AC-001/MUT-001.
  • MUT-002 (AC-003): neutralizar o ramo sem-lista para deixar a ref passar em vez de reescrever faz a lane unit e a lane e2e reprovarem, ambas reportando AUR-472/AC-001/MUT-002.