Pular para conteúdo

AUR-318 — congelar taskmaster como histórico

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

Contrato

Este card congela .taskmaster/ como histórico: seu estado done e suas instruções são preservados somente como input de auditoria e são ignorados pela fila do board. Uma cópia bounded do tree legado (21 arquivos, ≤ 64 arquivos, ≤ 1 MiB, com as 188 tasks/subtasks em done e as instruções de CLAUDE.md embutidas) vive em tests/characterization/legacy/taskmaster/snapshot. O fixture Go tests/characterization/legacy/taskmaster/fixture.go modela a fronteira de seleção da fila:

  • FeedBoardQueue nunca admite um candidato com origem taskmaster; cada um é preservado integralmente como AuditRecord com disposition audit-only;
  • PromoteDoneToBoard recusa qualquer transição derivada de .taskmaster com o erro tipado ErrLegacyTransitionRefused, mapeado para exit 1 por PromotionExitCode; um candidato nativo do board continua promovível (exit 0), o que distingue o freeze de um no-op que recusa tudo;
  • LoadLegacySnapshot é fail-closed: bounds de arquivos/bytes, symlinks e árvore inválida rejeitam antes de qualquer parse;
  • AuditSummary só emite contagens; títulos, instruções e identificadores hostis (inclusive um canary injetado) nunca alcançam logs ou observações.

.taskmaster, go.mod e go.sum são somente leitura. O acceptance compara byte a byte o tree vivo .taskmaster com a cópia de auditoria antes e depois de todas as camadas (taskmaster_bytes_changed sai 1) e a integração repete a comparação por dentro (CompareTrees), observada como taskmaster_bytes.

Relatório canônico

A integração emite uma linha por fato observado:

observation<TAB>value<TAB>effect

O baseline selado é tests/characterization/legacy/taskmaster/expected.tsv com exatamente 8 observações: 188 registros de auditoria, 2 candidatos board admitidos, promoção board exit:0, promoção taskmaster exit:1 recusada, 0 itens de fila vindos de .taskmaster, 13370 bytes de instruções embutidas, bytes identical e 188 tasks done auditadas. Linhas ausentes, extras ou divergentes saem 1.

Camadas executáveis

  • TestAUR318 prova recusa tipada, exclusão da fila, preservação audit-only e redaction do canary no sumário.
  • ContractAUR318 prova bounds fail-closed do snapshot, disjunção fila/taskmaster, preservação completa da auditoria, determinismo, recusa estável e sensibilidade real de CompareTrees a bytes divergentes.
  • IntegrationAUR318 alimenta a fila com a cópia real, tenta a promoção proibida e emite as 8 observações.
  • E2EAUR318 chama o acceptance pelo selector de integração e exige o marcador produzido somente depois da comparação canônica.

Cada .go declarado é copiado para um módulo temporário com uma bridge *_test.go; o selector citado é uma função executada por go test, nunca um nome aceito sem asserções. A tag aur318_characterization isola os fontes do build normal. GOPROXY=off, GOSUMDB=off e GOTOOLCHAIN=local impedem resolução externa; somente stdlib e o próprio módulo são importados.

Exemplo executável

./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-318
bash tests/acceptance/AUR-318.sh TestAUR318
bash tests/acceptance/AUR-318.sh ContractAUR318
bash tests/acceptance/AUR-318.sh IntegrationAUR318
bash tests/e2e/AUR-318.sh E2EAUR318

O primeiro comando é o acceptance oficial; os demais são seletores de diagnóstico num ambiente Go+Bash equivalente ao profile pinado.

MUT-001

Remover a guarda de PromoteDoneToBoard (promover uma task done do taskmaster para done do board) mantém a fila vazia mas muda a observação promote_taskmaster_done para exit:0. O wrapper oficial sai 1 e emite exatamente:

AUR-318/AC-001/MUT-001

Restaurar o byte original reproduz o GREEN exato. Falha de build, loader, ferramenta, imagem ou container é inconclusiva e não conta como RED.

Falhas e diagnóstico

  • exit 0: camadas executaram asserções reais, relatório coincidiu com o baseline e .taskmaster permaneceu byte a byte idêntico;
  • exit 1 com AUR-318/AC-001: Congelar taskmaster como histórico ausente: algum item de .taskmaster entrou na fila (comportamento ausente);
  • exit 1 com MUT-001: uma transição derivada de .taskmaster foi aceita;
  • exit 1 com taskmaster_bytes_changed:*: o tree vivo divergiu da cópia de auditoria;
  • exit 1 com characterization_mismatch: outra observação divergiu do baseline;
  • exit 1 com <layer>_exit:<n>: uma função de teste real falhou;
  • exit 64: selector desconhecido; exit 79: harness indisponível, nunca RED.

Logs de camada só aparecem em falha, após a checagem do canary, limitados às primeiras 80 linhas; stdout/stderr do wrapper OCI ficam sob os 64 KiB do profile.

Compatibilidade, migração e rollback

Nenhuma task de .taskmaster é apagada, migrada ou convertida em card. A caracterização é o estado before permanente do backlog legado. Rollback: reverter somente os paths do AUR-318 e repetir AC-001; nenhum efeito externo precisa ser desfeito.