8.4 KiB
Assumptions — premissas e decisões desta RI
Este documento explica o que foi assumido ao construir a Reference Implementation (RI) e
por quê, distinguindo isso do que é garantia arquitetural da arquitetura de
referência. É uma síntese — não uma cópia — do histórico de decisões registrado
em docs/adr/; cada ADR continua sendo o registro canônico de uma decisão
individual, este documento agrupa o "porquê" por tema para quem está avaliando a RI.
Público-alvo: quem vai avaliar ou adaptar esta RI para um cenário real e precisa saber o que foi assumido versus o que é garantia da arquitetura.
Escopo geral
Assumimos que uma RI prova propriedades de segurança, não é um produto pronto para produção.
Toda decisão abaixo prioriza demonstrar de forma verificável os invariantes da arquitetura
(MaximumEntitlement como teto, fail-closed, nunca elevar privilégio por contexto) sobre
completude operacional (HA, escala, UI). Onde as duas coisas colidiram, escolhemos a RI mais
simples que ainda prova a propriedade real contra uma dependência real — nunca um mock do
próprio ponto que estava sendo testado.
Identidade e PDP: tecnologias fechadas, não hipóteses a revisitar
Assumimos Keycloak como Identity Provider e OPA/Rego como PDP porque são OSS (Apache-2.0) e
aderentes a padrões abertos (OAuth 2.1/OIDC, Rego), não por preferência arbitrária. Isso
resolve duas lacunas que a arquitetura de referência deixava abertas (README.md §48, perguntas
1 e 3) com uma decisão técnica definitiva, não uma suposição — nunca foram revisitadas ao longo
da implementação. Ver docs/adr/ADR-019-identity-extension.md,
docs/adr/ADR-025-engine-do-pdp.md.
Rejeitamos um engine de PDP próprio em Python (mais controle, mas reinventa avaliação de política sem ganho real) e Cedar (também seria adequado, mas OPA tem maior aderência a "padrões abertos" e uma comunidade Rego mais madura para o escopo desta RI).
Referência operacional Python/LangGraph/Langfuse (Agent Platform OCI)
Assumimos como referência operacional concreta o projeto Agent Platform OCI de Christiano
Hoshikawa (docs/research/hoshikawa-agent-platform-oci.md) para a camada de
LangGraph/Langfuse/FastMCP, em vez de inventar um padrão genérico do zero — mais rápido, menos
decisões ad hoc, e um ponto de comparação real do que "orquestração multiagente" significa na
prática. Reaproveitamos dessa referência: StateGraph com router/supervisor por backend,
checkpointing plugável, taxonomia de observabilidade IC/NOC/GRL com instrumentação híbrida
(spans automáticos + eventos manuais fail-open), identity.yaml/BusinessContext para
normalizar identidade entre canais, FastMCP como padrão de servidor MCP.
Rejeitamos explicitamente um único elemento dessa referência: seu modelo de autorização de
tools por allowlist estático avaliado sobre um agent_id que chega como dado do payload de
entrada da conversa, não como claim de uma identidade autenticada verificada
independentemente — o próprio projeto de referência admite que isso não substitui
autenticação/autorização real. Essa é exatamente a forma de anti-padrão que a arquitetura
proíbe (ADR-001/ADR-002/ADR-003). A RI reaproveita a forma de proxy desse Gateway
(contratos de invocação/resultado, cache por tool, catálogo) apenas na camada de Fabric/UX
conversacional — a decisão ALLOW/DENY continua 100% no nosso PEP/PDP, nunca em agent_id
autodeclarado. Ver docs/adr/ADR-022-referencia-hoshikawa-agent-platform-oci.md,
docs/adr/ADR-023-autorizacao-nunca-vem-do-payload.md. Este achado também motivou um cenário
adversarial dedicado (tests/adversarial/test_payload_identity_spoofing.py).
Downstream identity
Assumimos token exchange (RFC 8693) quando o backend suporta OIDC, com fallback para
service account isolado por adapter quando não suporta — porque reutilizar sempre o token do
client (a alternativa mais simples) é exatamente o "blind token passthrough" que a arquitetura
proíbe (inbound ≠ outbound identity). Ver docs/adr/ADR-020-downstream-identity.md.
Granularidade de client profile
Assumimos domínio + risk tier (ex.: Sales.Read=R1, Sales.Write=R2,
Finance.Payments=R3) como a granularidade de client profile, em vez de um client "enterprise
admin" único ou apenas domínio sem tier — porque só essa granularidade permite provar
segmentação de blast-radius entre tiers de risco dentro do mesmo domínio (README.md §7, §17,
§31). Ver docs/adr/ADR-008-segmentacao-por-dominio-e-risco.md.
Profile Intelligence: stub determinístico, não "IA de verdade"
Assumimos que Profile Intelligence "genérica e substituível" (README.md §6.10) não prescreve
algoritmo, taxonomia nem fonte de dados real — porque a arquitetura de referência não define
nenhum desses, deliberadamente. A RI implementa um stub baseado em regras determinísticas sobre
atributos sintéticos, atrás de uma interface substituível (ProfileIntelligenceProvider), que
cumpre o contrato, não a "inteligência" em si. Um fork de produção substitui apenas a
implementação, nunca o contrato (ProfileView) nem o ponto em que ele se conecta (nunca ao PDP).
Escopo de domínios: dois, não federação completa
Assumimos dois domínios de exemplo (Sales, Finance) como suficientes para provar segmentação/blast-radius entre domínios distintos, sem precisar de federação multi-domínio completa. Federação fica deliberadamente fora de escopo desta RI — é tratada no roadmap da arquitetura de referência como uma fase posterior (§47, Fase 5), não uma lacuna de implementação.
Ambiente: 100% local via Docker Compose
Assumimos que uma RI roda inteiramente local via docker compose, com separação de
ambientes demonstrada por overlay de configuração (config/env/{dev,ci}.yaml) em vez de
infraestrutura cloud/híbrida real — provar a arquitetura não exige multi-cloud, e simular
multi-cloud sem multi-cloud real não provaria nada além da própria simulação.
Substituições para viabilizar teste sem infraestrutura pesada
- Servidor JWKS local como stand-in de Keycloak na maior parte da suíte e2e — válido porque
o que está sendo testado ali é a lógica de validação de token (assinatura,
exp,iss,aud, extração deazp), que é idêntica contra qualquer JWKS RS256 válido. A integração de protocolo real com Keycloak (grantclient_credentials, claims reais emitidas por um IdP real, RFC 8693) é coberta à parte, contra um Keycloak 26.7.3 real via Docker (tests/e2e/test_real_keycloak.py) — não é o mesmo teste, é um teste complementar que cobre exatamente o que o stand-in não pode. - SQLite em vez de Postgres para o Registry e para o checkpointer do LangGraph — válido para
provar o contrato/comportamento (schema, lifecycle, pausa/retomada de grafo); não é uma
alegação sobre desempenho ou concorrência sob carga de produção (ver
Production-Recommendations.md). policy_versioncomo hash de arquivo, não revisão de bundle OPA real — um SHA-256 do conteúdo dos.regoem disco é suficiente para provar quepolicy_versionflui ponta a ponta em toda decisão e evento de auditoria; não é uma alegação sobre distribuição de política em um cluster de produção.
Itens deliberadamente fora de escopo
- Adapter REST sem caminho ao vivo pelo Gateway (EP-06-T04): implementado e testado standalone; nenhum backend de exemplo desta RI é REST, então não há um caminho ao vivo através do Gateway exercitando-o. Só passaria a importar se um domínio futuro precisasse de um backend não-MCP-nativo.
- LangGraph deliberadamente ausente do Gateway/Fabric — usado apenas onde há estado,
ciclos ou checkpointing reais (Service Orchestrator, EP-11; handoff do Agent Runtime, EP-12-T03).
Nenhum roteamento simples (Gateway EP-05, Fabric EP-06, Offering Filter EP-10) usa LangGraph —
usar um grafo com estado para um roteamento sem estado seria over-engineering, não uma escolha
neutra. Ver
docs/adr/ADR-021-escopo-langgraph-langfuse.md. - Rate limiting e anti-replay: gaps reais e conscientes, não esquecimentos — documentados e
cobertos por teste adversarial dedicado (
tests/adversarial/test_protocol_identity.py), nunca silenciosamente ignorados. VerProduction-Recommendations.mdpara o que um deployment real precisa adicionar.