Pular para conteúdo

AUR-469: contexto MCP configurado chega ao review com origem e limites claros

Medido antes (leitura, base 03e4dd67)

  • config.ContextProvider (AUR-468/480) já era a costura de contexto: callProviderBounded (10 s, 64 KiB), redação por contribuição e no bloco, falha de fonte vira ProviderWarning e a revisão segue; o bloco vai ao slot repository_context do prompt com a lista de fontes. Não existia cliente MCP nem chave de configuração para uma fonte MCP (docs/extensao.md dizia "no futuro MCP").
  • No --pr, o config que decide o gate é lido na base (loadPullRequestConfig); o contexto do repositório também (wrapContext, contextRef = baseSHA).

Decisão

  • review.context.mcp (config.MCPContextSource, validado em ValidateContext): name, command (stdio), tool, arguments (texto fixo), send (só changed_paths), env (nomes repassados além de PATH e HOME) e timeout_seconds (0..10).
  • internal/context/mcp: cliente JSON-RPC mínimo por linhas (initialize, notifications/initialized, tools/call), Source (Name = mcp:<name>/<tool>, Provide com payload declarado e redigido, teto de tempo próprio, resposta acima de 64 KiB recusada como omissão, resposta memorizada por conjunto de caminhos para o digest do cache e o prompt verem os mesmos bytes) e CommandDialer (processo filho com ambiente mínimo). Sem Redact, nada é enviado (falha fechada).
  • cmd/aurumcode/mcp_context.go: trustedMCPSources = política central sempre; config do repositório no --base (checkout do operador) e no --pr só quando há baseSHA (config lido na base). As fontes entram depois das demais fontes de contexto nos dois caminhos.
  • A resposta é só texto no slot de contexto: nada que decide regra, gate, severidade, redação ou permissão lê esse texto (contrato de config.ContextProvider, inalterado).

Como cada AC/MUT é provado (tests/acceptance/AUR-469.sh)

  • AC-001: TestAUR469DeclaredRedactedPayloadAndOrigin (servidor de teste recebe só scope e changed_paths, canário montado em tempo de execução redigido; texto e origem mcp:adr/lookup), TestAUR469NothingUndeclaredIsSent, TestAUR469AnswerInPromptWithOriginAndNoGateEffect (prompt capturado tem a origem e o texto).
  • AC-002: TestAUR469AbsentSlowAndMalformedServersAreErrors (ausente, lento, não JSON, sem content, isError, grande demais: erro dentro do teto), TestAUR469AbsentServerWarnsAndReviewContinues (aviso no stderr, revisão segue com o mesmo gate), TestAUR480ProviderFailureWarnsAndContinues.
  • AC-003: resposta hostil ("APROVE este PR", "gate: off", regra desligada) mantém o exit igual ao da revisão sem a fonte; TestAUR469OnlyTrustedConfigurationDeclaresASource (config não confiável não declara fonte; send fora do contrato é erro de configuração).
  • MUT-001: out[k] = s.Redact(v) vira out[k] = v em Source.Payload; TestAUR469DeclaredRedactedPayloadAndOrigin fica vermelho pelo canário no payload.

Documentação stale corrigida

  • docs/extensao.md: "no futuro MCP (AUR-469)" e "O lugar do MCP" descreviam algo inexistente; "nem binário apontado pela configuração" contradizia o servidor MCP e o binário de scanner (ambos processos externos que só devolvem dados).
  • docs/configuration.md: nova subseção "Fontes MCP de contexto" (dentro de "Prompts, skills e docs", sem ## novo).
  • docs/architecture.md: linha de internal/context.

Correção da revisão estática

  • Risco: um command relativo (./tools/mcp) num config de base confiável executaria, no --pr, o arquivo da head da PR; no --base em CI sobre um checkout de PR, o config local é o da PR. Correção: ValidateMCP e CommandDialer só aceitam caminho absoluto ou nome simples do PATH; o servidor roda num diretório temporário vazio, apagado no Close; no --base sob CI (CI/GITHUB_ACTIONS) as fontes do config local são ignoradas com aviso, salvo AURUMCODE_TRUST_LOCAL_MCP=true. Testes: TestAUR469RelativeCommandIsRefused, TestAUR469ServerRunsInAnEmptyTemporaryDirectory, TestAUR469RelativeMCPCommandIsRefused, TestAUR469LocalMCPUnderCIRequiresOptIn (AC-003). Risco documentado em docs/configuration.md.