AUR-592: Aurum para quem programa com agente de IA
Medido antes (base 959b71df)
- O parecer do Aurum só chegava na PR (CI) ou por
aurumcode review --baseno terminal. Nenhum agente de código (Claude Code, Codex, Cursor) tinha como perguntar ao gate antes do commit; não havia servidor MCP, skill de agente nem hook de pre-commit. runReviewWithconstruía a sessão--baseinline, e a resolução das regras de skill (catálogo da política e do repositório, regras dinâmicas) vivia dentro debaseReview.selectProvider: não havia como listar as regras que valem para um caminho sem rodar uma revisão.- A revisão local cobre
base..HEAD(commits), não o índice nem a árvore de trabalho (computeDiffemcmd/aurumcode/local_diff.go).
O que mudou
internal/mcpserver(novo): o adaptador MCP por stdio.jsonrpc.go: o subconjunto JSON-RPC 2.0 que o MCP exige, isolado num arquivo (uma mensagem por linha, notificações sem resposta, lote recusado, linha limitada a 1 MiB). Decisão: sem o SDK oficial Go (github.com/modelcontextprotocol/go-sdk), porque ele não está no cache offline de módulos e uma dependência nova exigiriago getcom rede e repin da imagem selada; o subconjunto (initialize,tools/list,tools/call,ping) é pequeno e tem testes de protocolo.tools.go: as quatro ferramentas (aurum_review,aurum_gate,aurum_rules,aurum_explain), cada uma com JSON Schema fechado (additionalProperties: false) e anotaçãoreadOnlyHint.args.go: decodificação estrita (DisallowUnknownFields) e validação antes de executar: a ref não começa por-nem contém..; caminhos são relativos ao repositório;finding_idtem 12 hex.gateway.go: a portaGateway(Review, Rules). O servidor não decide.decision.go: a decisão é lida da sessão (código de saída e motivo de inconclusivo dogate.Result);passsó com saída 0, revisão conclusiva e mudança não vazia. Mudança vazia entrebaseeHEADéinconclusive(empty_change): mais estrito que a CLI, de propósito, porque o agente que pergunta antes de commitar não pode ler "nada revisado" comopass.redact.go: o único ponto de redação; toda resposta (inclusive o stderr da sessão, que no gateway é um buffer e não o writer redigido da CLI) passa pelo filtro do processo e pelo filtro final da sessão.server.go: o laço stdio, o limite de tempo por chamada (--tempo; estourou éinconclusive,time_limit) e uma revisão por vez.cmd/aurumcode:review_base.go:newBaseReview, o único construtor da sessão--base, usado pela CLI e pelo servidor.skill_catalog.go:resolveSkillRules, a única resolução de catálogo e regras de skill, usada pela sessão e poraurum_rules.cmd_mcp.go: o subcomandomcp(flags--tempo,--limite), no registro único de comandos.mcp_gateway.go/mcp_rules.go: o gateway monta a linhareview --base <ref> --seguranca --exigir-qualidade(o agente só recebe respostas mais estritas que umreview --basepuro), rodasession.Rune lêgateRes,result,securityApartenotReviewed..agents/skills/aurum-review/SKILL.md(formato Agent Skills) e.agents/skills/aurum-review/hooks/pre-commit(hook opcional que revisa o índice numa worktree temporária).docs/agentes.md(nav),docs/index.md,docs/architecture.md(módulo e seção do adaptador),docs/configuration.md(seçãoCLI aurumcode mcp, que o--helpdo comando cita), tutorialdemo/tutoriais/agenteedocs/tutorials/agente.md, capturas.
Prova
Aceite (tests/acceptance/AUR-592.sh, go-shared)
| Seletor | O que prova | Última linha |
|---|---|---|
| AC-001 | cliente MCP em stdio lista as 4 ferramentas; aurum_gate/aurum_review dão o mesmo código de saída, o mesmo relatório e os mesmos achados bloqueantes (vs. auditoria) que review --base no mesmo diff (skill do repo + segredo); conformidade do protocolo |
AUR-592/AC-001/pass |
| AC-002 | sob AURUMCODE_POLICY, aurum_rules lista skills policy e repository; nenhum schema declara propriedade além de base/paths/finding_id |
AUR-592/AC-002/pass |
| AC-003 | nenhuma resposta contém o canário do diff; argumento extra/inválido recusado (-32602) sem a sessão rodar; provedor ausente, provedor que falha e mudança vazia são inconclusive |
AUR-592/AC-003/pass |
| AC-004 | skill com front matter name/description que manda chamar aurum_gate; página com claude mcp add, .mcp.json, Codex, Cursor na nav; tutorial com os casos e run.sh --check |
AUR-592/AC-004/pass |
| MUT-001 | o gateway com caminho de gate próprio (só resolve/evidence/model e decide por contagem de achados error) compila e reprova TestMCPGateIsTheReviewSessionGate (o relatório diverge do review --base) |
AUR-592/MUT-001/rejected |
| MUT-002 | sem o ponto de redação (toolResult(answer)), TestEveryAnswerIsRedacted reprova: o canário aparece em achados, relatório, stderr e linhas do gate |
AUR-592/MUT-002/rejected |
Escopo da MUT-002: ela reprova no servidor, com um gateway que entrega texto cru. De ponta a ponta a sessão já redige os campos do modelo e o relatório; o ponto de redação do servidor é a segunda barreira e a única sobre o stderr da sessão, que no gateway é um buffer.
O relatório de aurum_review é o stdout da sessão depois do filtro de
redação inteiro; por isso AC-001 compara com Redact(stdout da CLI). Quando
o relatório cita security/hardcoded-secret: <título>, o filtro reescreve o
título (a CLI evita isso redigindo campo a campo); os achados estruturados
mantêm rule_id intacto.
Tutorial e regressão (execução real)
- Imagem do produto construída uma vez desta árvore
(
AURUMCODE_TUT_IMAGE=aurum-tutoriais:aur592 AURUMCODE_TUT_REBUILD=1),demo/tutoriais/agente/run.sh alle os outros 18 tutoriais com-P4: todosrc=0;run.sh --checkdos 19:CHECK OK(sbom-dependency-track terminou com o casodown). bash scripts/docs/capturas.sh:capturas: 239 imagens no manifesto;bash scripts/docs/build.sh: 0 avisos.go vet ./...limpo;go test -p 1 ./...sem falha.- Aceites (go-shared): AUR-592, 576, 580, 593, 572, 561, 562, 563, 564 e 588
all: pass. AUR-443 falha com as mesmas 5 linhas--- FAILemmain(959b71df) e neste ramo: defeito anterior a este card. - Selado:
oci-run --profile go-unit-offline-v1 --card AUR-592:"exit_code":0. No selado sócmd/aurumcodeé materializado (paths do card), então a identidade da árvore deout/.imagemnão pode bater; o AC-004 então exige os 4 casosokcontraexpected/e a divergência ser só de árvore. A árvore é conferida ondecmd/está inteiro (AUR-561..564, CI e o--checklocal).
Decisões e pendências
- O hook ficou em
.agents/skills/aurum-review/hooks/pre-commit, e não emscripts/hooks/, porquescripts/não está nospathsdo card.docs/configuration.mdfoi tocado fora dospaths(a seção que o--helpdo comandomcpcita). - A revisão por MCP vê commits (
base..HEAD); o índice é coberto pelo hook. Revisar a árvore de trabalho sem commit ficaria para um card próprio (uma fonte de diff nova na sessão, não no servidor). - Defeito existente, fora deste card: com
AURUMCODE_CACHE_DIRdefinido, uma segunda execução dereview --base --segurancasobre o mesmo conteúdo reaplica o achado de segurança emReview.Issuespelo reaproveitamento de veredito e o imprime duas vezes (o teste de AC-001 usa cache novo por execução para comparar sessões equivalentes).