AUR-587: guia de extensão no site e tutorial executável de exemplo
Medido antes (base 9c685fde)
- O site publicava
docs/architecture.md(em inglês) com uma seção "Extension points" curta; não havia guia de extensão nem tutorial que mostrasse como estender o produto. - O registro de engines (
internal/scanner/engines) importava sógitleaksesemgrep; oDockerfilecompilavago buildsem tags. demo/tutoriais/_lib/tutorial.shconstruía uma única imagem por árvore, sem build args;out/.imagemregistravatree,dockerfileeimage.
O que mudou
docs/extensao.md("Estendendo o Aurum", pt-BR, na navegação demkdocs.ymllogo após Arquitetura): os quatro pontos de extensão com o contrato real (engine de scanner:scanner.Scanner,Request,Report,Finding.ToIssue,Engine,Register,Executor,FailureReason,quality_gates.scanners,required; ferramenta de deliberação:deliberation.Tool,Result,Limits,LimitError,Transcript, o manifesto deinternal/review/tools; skill: arquivo listado,SKILL.md, catálogo em camadas; fonte de contexto:config.ContextProvider,ProviderTimeout,MaxProviderContributionBytes, o lugar do MCP, AUR-469), um exemplo mínimo por ponto e "O que NÃO é ponto de extensão" (plugin dinâmico, texto do modelo alterando o gate, MCP como autoridade, engine fora do registro).internal/scanner/engines/exemplo: engine de exemplo sem binário externo; reporta cada linha da árvore revisada (sem.git) que contém a marcaEXEMPLO-ACHADO(regraexemplo:marca, severidadeerror, origem e categoriaexemplo,Report.Versionexemplo 1; arquivo acima de 1 MiB é pulado; árvore ilegível é erro, logo inconclusivo). O pacote não se registra:internal/scanner/engines/exemplo_registro.go(//go:build aurum_exemplo) é o único que o importa e chamascanner.Register.Dockerfile:ARG GO_TAGS=""no estágio builder, usado emgo build -tags "$GO_TAGS". Sem o argumento o binário é o de antes.demo/tutoriais/_lib/tutorial.sh:TUT_BUILD_ARGS(declarado norun.shantes dosource;AURUMCODE_TUT_BUILD_ARGSsobrescreve) vira--build-arg; com build args a tag ganha o sufixo-<12 hex dos args>(também sobAURUMCODE_TUT_IMAGE), então a imagem padrão dos outros tutoriais nunca é sobrescrita;out/.imagemganhabuild_args=e o--checkreprova build args diferentes (linha ausente vale vazio);tut_image_padraoeTUT_RUN_IMAGEdeixam um caso rodar a imagem padrão.- Tutorial
docs/tutorials/extensao.md+demo/tutoriais/extensao(TUT_BUILD_ARGS="GO_TAGS=aurum_exemplo"), casosengine-no-gate,skill-no-prompt,ferramenta-pedidaefalha-binario-padrao; registrado emdocs/tutorials/README.md,demo/tutoriais/README.mdedocs/index.md(seção "Estendendo o Aurum", que liga guia e tutorial). Nav: o hookscripts/docs/hooks.pyinjetatutorials/extensao.mdna seção Tutoriais (sem mudança no hook). docs/architecture.md: só edições aditivas (o AUR-583 edita o mesmo arquivo em paralelo): uma linha na tabela de pacotes parainternal/scanner/engines/exemploe o parágrafo "Veja o guia de extensão" no fim de "Extension points".- Testes:
internal/scanner/engines/exemplo/exemplo_test.go(achados determinísticos, árvore limpa completa, raiz ilegível inconclusiva, sem opções);internal/scanner/engines/registro_padrao_test.go(!aurum_exemplo: não registrada,config.Parserecusaengine: exemplo);registro_exemplo_test.go(aurum_exemplo: registrada com origemexemplo, Parse aceita);guia_test.go: cadapkg.Nomeepkg.Tipo.Membrocitado no guia (pacotesscanner,exemplo,deliberation,tools,skills,config,llm) existe nogo/astdo pacote (nomes de topo, métodos por receptor, campos de struct, métodos de interface), um conjunto mínimo do contrato é citado e há ao menos 25 citações distintas.
Fora do escopo / pendente
- AC-004 parcial:
docs/architecture.mdcontinua em inglês. O briefing adiou a tradução para depois do AUR-583 (que edita a tabela de camadas ecmd/aurumcode/structure_test.go/architecture_doc_test.go), para evitar conflito. A tabela continua lida porarchitecture_doc_test.go, que passa. A tradução fica como pendência deste card ou de um card seguinte. - Plugin dinâmico, MCP real (AUR-469), mudança de contratos existentes, engine de exemplo no binário padrão: non-goals.
Como cada AC/MUT foi provado
Aceite: tests/acceptance/AUR-587.sh (seletores all, AC-001..AC-004,
MUT-001, MUT-002). O selado não tem docker: a engine é provada por
go list -deps/go test com e sem a tag, e o tutorial pelo out/ gravado
e --check.
- AC-001: guia no nav (
- Estendendo o Aurum: extensao.md), as cinco seções, eTestExtensionGuideCitesTheRealContractverde. Site:bash scripts/docs/build.sh(que rodamkdocs build --strict) com 0 warnings; nosite/search/search_index.jsonconstruído, "engine", "ferramenta", "skill" e "ContextProvider" têm hits emextensao/. - AC-002:
go list -deps ./cmd/aurumcodecontém o pacote de exemplo 0 vezes sem tag e 1 vez com-tags aurum_exemplo;TestDefaultBuildRefusesExampleEngine(sem tag) eTestTaggedBuildRegistersExampleEngine(com tag) verdes;run.sh --checkdo tutorialCHECK OK; oout/tem a linha do gate comorigem exemplo,auditoria blocking_findings: ... origin=exemplo,sarif result: ... origin=exemplo,unknown engine "exemplo"no binário padrão ebuild_args=GO_TAGS=aurum_exemploemout/.imagem. - AC-003:
prompt: Uma funcao faz uma coisa so. MARCA-SKILL-EXEMPLOe o eco da fixture noout/skill-no-prompt.log;auditoria chamada: rodada=1 ferramenta=scanner_exemplo status=executed resultado=1 achado(s)noout/ferramenta-pedida.log. - AC-004 (parcial, ver acima):
TestAUR558ArchitectureDocCitesEveryInternalPackageverde;architecture.mdeindex.mdligam o guia;index.mdliga o tutorial. - MUT-001: sem
exemplo_registro.goo pacote some do binário com tag, o teste com tag falha comexample engine not registered, e umout/sem a origemexemplofaz o--checkreprovar (DIVERGENCIA caso=engine-no-gate). - MUT-002: acrescentar
scanner.Scanner.Scanao guia reprova o teste do guia (cites names the packages do not declare: scanner.Scanner.Scan).
Execução real do tutorial
Imagens construídas desta árvore (AURUMCODE_TUT_IMAGE=aurum-tutoriais:aur587;
a do tutorial é aurum-tutoriais:aur587-<sufixo dos args>):
extensao/engine-no-gate: exit 3,(severidade error, limiar error, origem exemplo, secao repo).extensao/skill-no-prompt: exit 0, o prompt traz a skill e a fixture ecoa.extensao/ferramenta-pedida: exit 3,rodada 1 scanner_exemplo({}) executed: 1 achado(s).extensao/falha-binario-padrao: exit 1,quality_gates.scanners[exemplo].engine: unknown engine "exemplo" (registered: gitleaks, semgrep).
Os 18 tutoriais foram reexecutados em paralelo com a imagem desta árvore (o
Dockerfile e internal/ mudaram, então todo out/.imagem mudou) e o
out/ de cada um foi commitado; run.sh --check passa em todos.
Config do tutorial fora de .aurumcode/
TestAUR575ExistingConfigsStayValid (internal/config) valida, com o binário
padrão, todo config.yml sob um diretório .aurumcode em demo/, tests/ e
docs/. A configuração com engine: exemplo só vale no binário com a tag, por
isso o tutorial a guarda como demo/tutoriais/extensao/config-engine.yml e
config-ferramenta.yml; o run.sh (repo_engine) a copia para o
.aurumcode/config.yml do repositório descartável e apaga esse repositório ao
fim do caso (apaga_repo). Sem mudar o teste nem internal/config.
Regressão (container go-shared, em série)
go vet ./... && go vet -tags aurum_exemplo ./internal/scanner/... && go test -p 1 ./...: verde.AUR-587.sh all→AUR-587/all/pass;AUR-577.sh all→AUR-577/all/pass;AUR-580.sh all→AUR-580/all/pass;AUR-561..564 allverdes;AUR-572.sh alleAUR-586.sh allverdes.AUR-560.sh allfalhava comindex-missing-capabilitytambém nomain74121dba (seções deconfiguration.mdsem link no índice:gate.triage, deliberação e "Quais arquivos saem da revisão como documentação").docs/index.mdpassou a ligar as três;AUR-560.sh all→AUR-560/all/ok.bash scripts/docs/build.sh: 0 warnings.- Selado:
oci-run --profile go-unit-offline-v1 --card AUR-587→exit_code 0.