Pular para conteúdo

AUR-590 — reparos medidos

Cada item: causa medida, correção, prova. Comandos rodados no container compartilhado (aurum-go, imagem aurum-dev-go:1.27.1-2026-10-02, git 2.54.0), salvo indicação.

Resumo

Item Estado Causa medida
1. testes git corrigido fixture herdava a configuração git global do ambiente (HOME=/tmp compartilhado), não o git 2.54
2. panic em internal/prompt corrigido mustDefaultSlotLimits/mustCatalogIDs faziam panic na inicialização
3. go list -m all offline corrigido (v2: repin) imagem selada pinada antes do go mod tidy do AUR-585
4. --check contagem corrigida; ordem só das linhas RESULTADO: grep -F por linha, sem contagem nem ordem
5. govet corrigido GOWORK não fixado; arquivo cgo saía do vet sem aviso
6. AUR-448/458/491 corrigidos (v3: integração do 448) ver abaixo

1. TestAUR536PackedRepositoryWithoutGitIsUnverifiable e TestOpenRepo_GitBinary_PackedObjects

Medido antes: na imagem atual os dois testes passam — isolados, no pacote inteiro, como uid 1000, com --pids-limit 24/64 e em go test -p 1 ./... completo (base 619b1b5e). O git 2.54 não é a causa. O que difere entre o container de desenvolvimento e o CI é o ambiente: os dois fixtures montavam o repositório com os.Environ(), e o aurum-go roda com HOME=/tmp, que vive enquanto o container vive e é compartilhado por todo agente. Um git config --global deixado ali (assinatura de commit, core.hooksPath, política de gc/pack) muda o que commit, gc e repack produzem. O container foi recriado no início desta sessão, então a configuração exata que derrubou os testes no AUR-584 não é recuperável; o mecanismo foi reproduzido:

# HOME com .gitconfig hostil (commit.gpgsign=true, gpg.program=false, hooksPath com pre-commit exit 1)
antes:  gitrepo_gitbinary_test.go:91: git [commit -q -m one]: exit status 1      FAIL internal/analyzer
antes:  aur536_test.go:517: git [commit -q -m initial]: exit status 1             FAIL cmd/aurumcode
depois: ok  internal/analyzer   /   ok  cmd/aurumcode

Correção: internal/gittest.HermeticEnv(home) — GIT_CONFIG_GLOBAL=/dev/null, GIT_CONFIG_NOSYSTEM=1, HOME e XDG_CONFIG_HOME privados (t.TempDir()), GIT_TERMINAL_PROMPT=0 e a identidade do fixture. Os dois testes (e o rev-parse do AUR-536) usam esse ambiente. internal/gittest/env_test.go prova o perigo (TestAmbientHomeConfigBreaksAPlainFixture: o fixture com o ambiente cru falha) e a correção pelos dois vetores (HOME hostil e GIT_CONFIG_GLOBAL hostil).

2. Sem panic( em internal/prompt

limits.go e rulecatalog.go guardam o erro de carga (defaultSlotLimitsErr, defaultRuleCatalogErr); EmbeddedDefaultsErr() os junta. O PromptBuilder recebe esse erro na construção e BuildPrompt, FixedOverheadTokens, FixedContentDigest (via BuildPrompt), ruleCatalogSection e ValidateRuleCatalog o devolvem: nenhum prompt é montado com tetos zero. DefaultRuleCatalog (var) e DefaultLimits() mantêm a assinatura (usados por tests/unit e tests/integration). Seams testáveis: loadSlotLimits(fs.ReadFileFS) e catalogIDs(load). Testes: TestLoadSlotLimitsReturnsErrors (ausente, malformado, não positivo), TestCatalogIDsReturnsLoaderError, TestBuilderRefusesAssemblyWhenDefaultsFailed, TestEmbeddedDefaultsLoad.

3. go list -m all com GOPROXY=off — repin (v2 do card)

Medido na imagem do lock antigo (aurum-bootstrap-go-bash@sha256:3aa0ce99...):

go: github.com/kr/text@v0.1.0: module lookup disabled by GOPROXY=off

Causa: o go.mod/go.sum assados na imagem são os do AUR-522 (83753f5d, repin 1.27.1-2026-10-02b). O AUR-585 (5622039f, go mod tidy) mudou o go.mod depois — removeu gorilla/mux, acrescentou github.com/kr/text v0.1.0 // indirect — sem repinar.

Correção, pelo procedimento do AUR-534:

docker build -f .board/oci/images/go-bash-1.27/Dockerfile \
  -t aurum-bootstrap-go-bash:1.27.1-2026-10-06 .
docker image inspect -f '{{.Id}}' aurum-bootstrap-go-bash:1.27.1-2026-10-06
sha256:b678437d5b61b54437940fd62d5716f237de249ed921765bd02b2077c945308c
  • Um primeiro build (sha256:4fc47013..., descartado) mostrou um segundo defeito: go mod download all acrescenta ao go.sum assado hashes que o go mod tidy não guarda (kr/pty v1.1.1 h1:, golang.org/x/sync v0.11.0), e o AC-004 do AUR-534 exige o go.sum assado idêntico ao do repositório. O Dockerfile agora copia de novo o go.sum do repositório depois do download (o cache de módulos continua com tudo). Medido na imagem final: go.mod e go.sum assados idênticos aos da árvore, go list -m all com GOPROXY=off sai 0, AUR-534.sh AC-004 → AUR-534/AC-004/pass.
  • Cadeia de digest: image dos 10 locks de .board/locks/oci que pinavam 3aa0ce99, lock_digest dos 9 profiles que apontam para eles, e lock_digest/image_set_digest de registry.v1.json (image_set_digest = sha256("aurum-bootstrap-go-bash@sha256:<id>"), fórmula conferida antes contra o valor antigo). docs/tutorials/operacao.md e o out/ do tutorial operacao mostram o digest novo.
  • AUR-534.sh all no selado continua vermelho por causa anterior a este card: go build ./... esgota o tmpfs de 512 MiB do profile (no space left on device). Medido igual no main com a imagem antiga (worktree temporário, mesma mensagem). O schema limita tmpfs_mb a 1024 e o limite vale para todo card do profile; não foi mudado aqui.
  • A imagem antiga aurum-bootstrap-go-bash:1.27.1-2026-10-02b (3aa0ce99) foi removida com docker rmi.

4. run.sh --check

Antes: cada linha de expected/ era procurada com grep -F em qualquer posição. Trocar um dos dois exit_code=3 de qualquer-linguagem/falha-extensao-desconhecida por exit_code=1 no out/ passava (o outro exit_code=3 satisfazia as duas linhas):

_lib antigo: caso falha-extensao-desconhecida: ok
_lib novo:   DIVERGENCIA caso=falha-extensao-desconhecida: trecho esperado 2 vez(es), encontrado 1: exit_code=3

Correção (demo/tutoriais/_lib/tutorial.sh, awk POSIX, roda no busybox): cada linha distinta de expected/ precisa ter, somadas as linhas do out/ normalizado, tantas ocorrências quantas vezes expected/ a repete; as linhas RESULTADO: precisam aparecer na ordem de expected/.

Ordem total não foi possível sem editar expected/ (fora de paths): medido sobre os 114 casos, exigir a ordem de todas as linhas reprova 25 casos, e a ordem só das linhas exit_code= reprova 3 (revisao/falha-nao-revisado, skills/falha-skill-inexistente, skills/repo-vs-politica: o expected/ lista exit_code=1/3 antes de exit_code=0, ao contrário da execução). Consumir uma linha distinta do out/ por linha esperada reprova 2 casos de dados-de-analise, que dividem uma linha longa da saída em vários trechos; por isso a contagem é por ocorrência. A ordem das linhas RESULTADO: vale nos 114. demo/tutoriais/README.md (fora de paths) ainda descreve o grep -F; docs/tutorials/README.md foi atualizado.

5. govet

  • GOWORK=off entra em Environment.Fixed. Prova comportamental: TestParentWorkspaceDoesNotReachVet põe um go.work no diretório acima da raiz (que não lista a raiz); com GOWORK=off o achado calc/calc.go:9 é mantido, sem ele o go vet falha e a varredura é lint_execution_error (MUT-002). TestGoChildHasWorkspaceOff prova que um GOWORK do processo não chega ao filho.
  • Arquivo cgo: com CGO_ENABLED=0 o vet exclui do pacote, sem aviso, todo arquivo com import "C". Agora, se um pacote com linha adicionada pelo intervalo tem arquivo assim, Run devolve ErrCgoUnvetted nomeando os arquivos e a varredura é lint_execution_error (inconclusiva). O executor descarta o texto do erro (só o motivo chega ao usuário); o nome do arquivo é provado no teste de unidade (TestCgoFileInTouchedPackageIsInconclusive), não na saída. Arquivo cgo em pacote não tocado não muda nada (TestCgoFileInUntouchedPackageIsIgnored).

6. AUR-448, AUR-458, AUR-491

  • AUR-491 (corrigido na doc): as flags acusadas (--config, --exit-code, --log-opts, --report-format, --report-path, --no-banner, --redact, --ignore-gitleaks-allow, --gitleaks-ignore-path, --relative, --unified) são do gitleaks e do git, citadas em prosa em docs/configuration.md (seções gitleaks e govet). O verificador conta toda flag fora de bloco cercado e ignora blocos que não são aurumcode. As linhas de comando foram para blocos sh próprios, e a prosa deixou de citar as duas flags do gitleaks soltas. AUR-491.sh all: AUR-491/all/pass; MUT-001: pass (mutation detected).
  • AUR-458 (corrigido no e2e): a causa não é o padrão do AUR-575 (exit 1 em erro de carga). tests/e2e/AUR-458.sh caso 4 esperava exit 2 (flag recusada) para review --pr ... --exigir-qualidade; desde 7eab0407 ("fail PR gate when required model review is inconclusive") o caminho --pr aceita e honra --exigir-qualidade, então o comando segue e sai 1 ao buscar o PR. O caso 4 agora prova que a flag é conhecida (nunca exit 2, nunca flag provided but not defined) e que o comando chega à busca do PR (exit 1, fetching pull request diff). AUR-458.sh all: AUR-458/AC-001/ok.
  • AUR-448: s3-grounded-finding-missing vinha do gate de escopo e evidência (internal/review/scope.go), que descarta achado sem impacto/evidência/verificação; os fixtures do aceite e de tests/unit/AUR-448.go ganharam esses três campos. TestAUR448, E2EAUR448 e AC-001-MUT-001 verdes. IntegrationAUR448 (v3): o teste esperava exit 1 e stdout vazio para review --base sem provedor; desde o AUR-449/AUR-458 esse caminho pula a revisão de qualidade, declara isso ("LLM quality review did not run", "quality review skipped; running deterministic analysis only"), roda a análise determinística e sai 0. O teste agora prova exatamente isso e mantém a mensagem do AUR-448 (formato completo do fixture, rule_id, discarded). Os casos com fixture passaram a comparar o que vem depois do bloco de resumo/diagrama do AUR-490 (aur448AfterDiagram), inteiro, e os fixtures ganharam evidência. AUR-448.sh all: AUR-448/AC-001/ok.
  • tests/acceptance/AUR-547.sh passou a esperar AUR-448 e AUR-458 verdes (todos os seletores do 448 com exit 0). AUR-547.sh all: AUR-547/all/pass.
  • AUR-448.sh e AUR-458.sh aceitam all (= AC-001).
  • demo/tutoriais/README.md descreve o --check por contagem e ordem.

Aceite

tests/acceptance/AUR-590.sh (v3). Selado (oci-run --card AUR-590, imagem b678437d...): AC-001 (skipped:no-git, pass), AC-002, AC-004, AC-005, AC-003 → pass; MUT-001, MUT-002 → red. AC-006 para em AUR-491: README does not state the product is free: os aceites aninhados leem arquivos fora de paths ∪ read_paths (README.md; tests/unit/AUR-458.go, tests/integration/AUR-458.go; tests/e2e/AUR-448.sh). No container compartilhado (árvore inteira): AUR-448.sh all → AUR-448/AC-001/ok, AUR-458.sh all → ok, AUR-491.sh all → pass, AUR-547.sh all → AUR-547/all/pass; lá o AC-003 falha porque o cache de módulos montado é o do host, não o da imagem.

Observação sobre o card

Para o selado verde, read_paths precisa de README.md, tests/unit/AUR-458.go, tests/integration/AUR-458.go e tests/e2e/AUR-448.sh (nenhum sobrepõe paths).