Pular para conteúdo

AUR-457 — Todo card done tem aceite que passa hoje

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

O que este card mediu, e por que o diagnostico herdado estava errado

O card foi aberto com a hipotese de que o exit 1 do AUR-002 era deriva de caracterizacao causada pelo AUR-424 (troca de gomarkdoc por go/doc), e que o exit 79 do AUR-001 vinha do arquivo tests/integration/AUR-001.go nunca ter compilado.

As duas hipoteses foram falsificadas por medicao. Nenhuma caracterizacao derivou. Nenhuma das duas falhas e reparavel dentro do contrato deste card.

Comando declarado e exit codes

./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-457
exit significado
0 AC-001 verde: toda assercao estatica passou
1 AUR-457/AC-001/<claim>: uma assercao real caiu
64 seletor desconhecido
65 boundary-overflow
79 infraestrutura ausente (ferramenta faltando); nunca e pass nem fail

Exemplo executavel sem segredo:

$ bash tests/acceptance/AUR-457.sh AC-001
{"card":"AUR-457","scenario":"AC-001","claims":6,"result":"pass"}

Diagnostico de falha: a mensagem em stderr tem a forma AUR-457/AC-001/<claim>: <detalhe>, onde <claim> nomeia exatamente a assercao que caiu.

Achado 1 — AUR-002 sai 1 por read_paths obsoleto, nao por deriva

Exit BRUTO medido no worktree candidato, profile selado bootstrap-readonly-v1:

  • antes: 1
  • depois: 1 (inalterado; nada dentro de paths do AUR-457 pode mudar isso)

stderr bruto do aceite, verbatim:

AUR-002/AC-001/baseline-drift: legacy command behavior drift (integration exit 1): AUR-002: legacy command emitted no aurumcode summary for input "source=go": # github.com/Mpaape/AurumCode/cmd/regenerate-docs cmd/regenerate-docs/main.go:665:36: undefined: rustExtractor.NewNativeExtractor cmd/regenerate-docs/main.go:670:38: undefined: csharpExtractor.NewNativeExtractor

Isso nao e deriva de caracterizacao. Prova: tests/acceptance/AUR-002.sh executa o bloco go run tests/integration/AUR-002.go como ultimo passo. Para chegar la, ele ja passou por manifest, digests de stdout/stderr, conteudo dos replays, linhas do legacy-baseline.md e o exemplo da documentacao — todos verdes. A baseline de caracterizacao esta intacta.

O que falha e compilar o sujeito:

  • 9ef5273 AUR-427: native doc-comment parsers for Rust and C# acrescentou internal/documentation/extractors/rust/native.go e internal/documentation/extractors/csharp/native.go, e passou a registra-los em cmd/regenerate-docs/main.go:665 e :670.
  • O read_paths do AUR-002 enumera os extractors arquivo a arquivo: internal/documentation/extractors/rust/extractor.go e internal/documentation/extractors/csharp/extractor.go. Os dois native.go nunca foram acrescentados.
  • O profile selado materializa apenas paths + read_paths do card em execucao. Logo os dois native.go ficam de fora do container, os pacotes rust e csharp chegam incompletos, e cmd/regenerate-docs deixa de compilar.

Contraprova no host, no MESMO candidato, com o mesmo codigo-fonte:

$ go build ./cmd/regenerate-docs
$ echo $?
0

Compila no host e nao compila no container selado. A diferenca entre os dois nao e o codigo — e o conjunto de arquivos materializados. A causa e materializacao.

Defeito secundario, real e nao reparado: o classificador de infraestrutura de tests/acceptance/AUR-002.sh reconhece command not found, go: downloading, module lookup disabled, missing go.sum, no required module provides, cannot find module e toolchain unavailable, mas nao reconhece o undefined: do compilador. Por isso uma falha de materializacao e reportada como baseline-drift com exit 1 (falha funcional) em vez de exit 79 (inconclusivo). O aceite acusa a caracterizacao de um defeito que ela nao tem.

Reparo real, fora do contrato deste card: acrescentar internal/documentation/extractors/rust/native.go e internal/documentation/extractors/csharp/native.go ao read_paths do card AUR-002. Esse arquivo vive em .board/cards/, que esta em forbidden_paths do AUR-457. Fica registrado como follow-up para o coordenador.

Achado 1b — com a materializacao reparada, a deriva real aparece: 2 e o numero certo

Com o read_paths do AUR-002 corrigido para a forma de diretorio (479827a), o undefined: sumiu e o aceite passou a cair mais fundo, em tests/integration/AUR-002.go, docs != 1. A deriva de comportamento existe de verdade — estava escondida atras do erro de compilacao.

Reproduzido no host, materializando exatamente paths + read_paths do AUR-002 e rodando cmd/regenerate-docs com a fixture de cada caso:

input resultado documentos gerados
source=go docs=1 failed=0 go/root.md
source=go+java docs=1 skipped=1 languages_skipped=java go/root.md
source=go+python+gomarkdoc-error docs=2 failed=0 result=ok go/root.md, python/module.md

Os dois documentos do terceiro caso, na integra:

--- title: Root - Go / permalink: /go/root/ ---
# Package main
## Functions
#### func Main
func Main()
--- title: Module - Python / permalink: /python/module/ ---
# Python Module Documentation
Fixture module.

2 e o numero certo. Nao sao duplicata nem lixo: sao linguagens diferentes, diretorios diferentes, permalinks diferentes, e cada um deriva do proprio insumo da fixture — func Main() de main.go e a docstring """Fixture module.""" de module.py.

A causa e exatamente a que o card previa. A fixture desse caso instala um stub gomarkdoc que sai 7 para simular a queda de uma ferramenta externa. Sob o desenho antigo isso derrubava a extracao de Go, e o caso registrava a falha silenciosa que a caracterizacao fixava: result=partial docs=1 failed=1 com exit 0. O AUR-424 trocou o subprocesso gomarkdoc pela go/doc da biblioteca padrao, entao a extracao de Go nao chama mais ferramenta externa nenhuma e o stub nao tem mais o que quebrar. O documento de Go passa a ser produzido, e o caso rende dois.

Ou seja: a falha silenciosa foi eliminada, nao escondida — o modo de falha (queda de ferramenta externa) deixou de existir para Go. O comportamento atual e o correto e a caracterizacao e que precisa ser rebaseada.

Rebase concluido nos artefatos concedidos

Com tests/characterization/legacy-baseline e tests/specs/AUR-002 acrescidos aos paths, o rebase foi feito caso a caso, nunca por varredura:

caso comportamento vivo marcador mudou?
complete-success result=ok docs=1 failed=0 complete nao
missing-extractor result=partial docs=1 skipped=1 failed=0 silent-failure nao — Java continua sendo pulado sem avisar, com exit 0; a falha silenciosa ainda ocorre e o marcador fica
extractor-error result=ok docs=2 failed=0 complete sim — a falha silenciosa foi eliminada

Alterado: tests/characterization/legacy-baseline/extractor-error.stderr (regravado para result=ok docs=2 skipped=0 failed=0 ... index_pages=2), manifest.tsv (linha extractor-error → docs=2,skipped=0,errors=0,writes=1, marcador complete), tests/specs/AUR-002/cases.yaml (novo expected_stderr_digest sha256:7b995be72c9248e08444b82627085875225a39172ca4434cd5f7867e10348d58, expected_effects, silent_failure: false, expected_marker: complete), e tests/acceptance/AUR-002.sh (contrato semantico do caso, silent_count == 2 → == 1, grep do replay, e o exemplo documentado silent_failures:1).

Em tests/integration/AUR-002.go o recibo tinha "silent_failures":2 literal: continuaria imprimindo 2 depois do rebase. Passou a ser derivado das proprias cases e a falhar se a contagem nao for 1 — recibo que nao pode ficar vermelho nao e evidencia.

Prova de que o novo baseline ainda e assercao real

Exigencia: se a extracao de Go voltar a afundar por ferramenta externa, o aceite tem que ficar vermelho. Provado restaurando a dependencia pre-AUR-424 — exec.LookPath("gomarkdoc") + honrar o exit code — dentro de internal/documentation/extractors/go/extractor.go:

AUR-002: input "source=go+python+gomarkdoc-error" generated no go/root.md (got python/module.md)
exit status 1

Restaurado o arquivo, o harness volta a exit 0 com {"cases":6,"replayed":6,"silent_failures":1,"result":"pass"} e git status internal/ limpo. A mutacao foi temporaria e nunca commitada.

O que ficou fora dos paths mesmo depois da expansao

Rodando tests/acceptance/AUR-002.sh AC-001 depois do rebase, o aceite para em:

AUR-002/AC-001/baseline-drift: research digest row drift: extractor-error

Faltam dois artefatos que nenhum dos dois lados previa, ambos fora de paths (nao sao forbidden_paths, apenas nao concedidos, e a regra do card e que fora de paths nenhum byte muda):

  1. .board/research/legacy-baseline.md:24 — a linha de digest ainda grava sha256:3bb1894d... | 0 | docs=1,skipped=0,errors=1,writes=1 | silent-failure. Precisa da nova tripla digest/effects/marker.
  2. docs/specs/AUR-002.md:58 — o exemplo documentado ainda diz "silent_failures":2; o aceite agora exige 1.

Nao afrouxei as duas checagens do aceite que leem esses arquivos para contornar o bloqueio: seria exatamente o gate-gaming que este card recusou duas vezes antes. oci-run --card AUR-002 so chega a 0 quando esses dois bytes mudarem.

Historico (antes da expansao de paths) — rebaseado dentro do contrato de entao: tests/integration/AUR-002.go trocou o docs != 1 por um oraculo por caso, preso ao conjunto de documentos e ao conteudo de cada um — titulo, permalink e um trecho derivado do insumo da propria fixture. Contagem passaria de novo com os dois arquivos errados; conteudo nao. Documento renomeado, pagina vazia, assinatura perdida, linguagem faltando ou pagina extra inesperada derrubam a assercao. Se o comportamento da era gomarkdoc voltar, ela fica vermelha.

Com o oraculo rebaseado, o harness passa do teste de documentos e cai mais fundo ainda:

AUR-002: extractor-error baseline-drift: command output differs from sealed bytes

Isso e o digest de stderr selado — expected_stderr_digest em tests/specs/AUR-002/cases.yaml e o replay tests/characterization/legacy-baseline/extractor-error.stderr, que ainda gravam result=partial docs=1 skipped=0 failed=1 e o marker silent-failure. Os dois sao paths do AUR-002, nao do AUR-457, e o silent_count == 2 de tests/acceptance/AUR-002.sh depende deles. Completar o rebase exige reduzir a contagem de falhas silenciosas de 2 para 1 e regravar o replay e o digest — trabalho do dono do AUR-002.

Achado 2 — AUR-001 sai 79 por ausencia estrutural de git na imagem

Exit BRUTO medido no worktree candidato, profile selado:

  • antes: 79
  • depois: 79

stderr bruto do aceite, verbatim:

AUR-001/AC-001/independent-tracked-source: git is unavailable; the embedded seal cannot authorize a pass

A imagem selada nao tem git:

$ docker run --rm --entrypoint sh aurum-bootstrap-go-bash@sha256:e8521445a6c1bc7c017258e9c71caf8eb78ee254862582c5d57d8a79d9413084 \
    -c 'command -v git || echo NO_GIT'
NO_GIT

tests/acceptance/AUR-001.sh:395-396 chama inconclusive — que sai 79 — assim que git falta. O proprio script documenta a intencao: "a host run compares it with the independent Git index, while a container without that index is inconclusive". O 79 e o caminho inconclusivo projetado, sob este profile, e nao um defeito do harness.

O reparo de compilacao aplicado a tests/integration/AUR-001.go nao podia ser a causa do 79: tests/acceptance/AUR-001.sh nao contem nenhum go run. A unica ocorrencia da string tests/integration/AUR-001.go no script esta na linha 579, dentro da lista declared_paths, e e apenas uma checagem de existencia — que fica depois do portao do git na linha 396 e portanto nunca e alcancada sob este profile. O reparo de compilacao continua correto por merito proprio (o arquivo de fato nao compilava), mas nao move o exit code.

Reparo real, fora do contrato deste card: ou o profile bootstrap-readonly-v1 ganha git, ou o AUR-001 passa a declarar um profile que o tenha. Ambos vivem fora de paths do AUR-457.

Conclusao para o board

O Outcome do AUR-457 — "o aceite de todo card marcado como entregue passa na arvore de hoje" — nao e alcancavel a partir do contrato deste card. Os dois bloqueios sao:

  1. read_paths obsoleto num card ja done (AUR-002), em forbidden_paths.
  2. imagem de profile sem git (AUR-001), fora de paths.

A clausula do proprio card — "ou, se a caracterizacao tiver perdido o proposito, declara isso explicitamente no spec com evidencia" — e o caminho tomado aqui, com a evidencia acima. A caracterizacao nao perdeu o proposito: ela esta intacta e continua sendo uma assercao real. Quem perdeu validade foi o read_paths que a alimenta.

Nao foi afrouxado nenhum seletor. tests/acceptance/AUR-002.sh, tests/unit/AUR-002.go, tests/integration/AUR-002.go e a baseline nao foram tocados: rebaixar o exit 1 para 79 sem provar a materializacao seria transformar um vermelho em inconclusivo, que e a forma exata do gate-gaming que este projeto combate.

O que AC-001 assere de fato

tests/acceptance/AUR-457.sh faz a verificacao estatica sobre os specs entregues e sobre o codigo vivo. Seis reivindicacoes, todas reais:

  1. subject-registers-native — cmd/regenerate-docs/main.go registra rustExtractor.NewNativeExtractor e csharpExtractor.NewNativeExtractor.
  2. native-sources-present — os dois native.go existem e definem esses construtores. Fica vermelho se o AUR-427 for revertido, renomeado ou movido.
  3. characterization-intact — as tres linhas de sumario aurumcode: result=... que tests/acceptance/AUR-002.sh exige continuam presentes, byte a byte, nos replays de tests/characterization/legacy-baseline. Fica vermelho se alguem rebasear a baseline.
  4. infra-classifier-gap — tests/acceptance/AUR-002.sh de fato nao reconhece undefined: como infraestrutura. Fica vermelho quando a lacuna for fechada, e nesse momento este spec precisa ser reescrito.
  5. spec-records-evidence — este arquivo registra os dois exits brutos, o SHA 9ef5273 e os dois read_paths ausentes.
  6. spec-declares-unreachable — este arquivo declara explicitamente que o Outcome nao e alcancavel pelo contrato do card.

Alem das seis, AC-001 executa de fato as tres camadas declaradas. tests/unit/AUR-457.go e tests/integration/AUR-457.go nao sao arquivos _test.go, entao go test ./... nunca os registraria — um seletor que o Go nunca roda e pior que um que roda sem asserir. AC-001 encena os dois pacotes, mais um _test.go ponte gerado, num modulo de rascunho sob TMPDIR (o profile selado so torna gravavel o paths do card) e os aponta de volta para o checkout real via AURUMCODE_ROOT. A lane recusa um verde vazio: exige exatamente um ok, ausencia de [no test files] e um --- PASS: TestAUR457Bridge explicito. Seletores individuais: bash tests/acceptance/AUR-457.sh TestAUR457, ... IntegrationAUR457, ... E2EAUR457.

MUT-001 verificado nas duas direcoes: alterar uma linha de sumario da baseline leva AC-001 a exit 1 com AUR-457/AC-001/MUT-001/characterization-intact, a lane Unit a exit 1 com selector-exit:unit, e o E2E a exit 1; restaurar o byte devolve exit 0 com a arvore limpa.

Lacunas declaradas

  • Os seletores tests/unit/AUR-457.go::TestAUR446 e tests/integration/AUR-457.go::IntegrationAUR446 que o card declara sao erro de template: TestAUR446 e IntegrationAUR446 ja existem em tests/unit/AUR-446.go:138 e tests/integration/AUR-446.go:121, nos mesmos pacotes unit e integration. Declara-los de novo seria erro de compilacao. Entregues como TestAUR457 e IntegrationAUR457.
  • Metade da cadeia agora e observacao direta, nao inferencia: o proprio aceite do AUR-457 saiu 0 no profile selado, e a sua reivindicacao 2 so passa lendo rust/native.go e csharp/native.go dentro do container. O read_paths do AUR-457 declara internal/documentation/extractors na forma de diretorio; o do AUR-002 declara os mesmos pacotes arquivo a arquivo. Mesma imagem, mesma arvore, mesmo commit: sob a forma de diretorio os native.go estao presentes e o card sai 0; sob a forma arquivo a arquivo o compilador nao os encontra. So a ausencia sob a forma do AUR-002 continua inferida do contrato de materializacao, e nao observada na arvore do container.
  • tests/e2e/AUR-002.sh esta em paths do AUR-457 mas nao existe na arvore e nao foi criado: o AUR-002 nao declara camada E2E.