|
| 1 | +# SPEC-019: Federated API Governance para Agentes Multiagente |
| 2 | + |
| 3 | +## Contexto |
| 4 | + |
| 5 | +**Gartner Hype Cycle 2026**: API Gateway/Brokering (Slope of Enlightenment, Moderado, 2-5 anos para Plateau) |
| 6 | +**Gap**: O ecossistema OpenCode não possui política federada de governança de API entre agentes — cada agente gerencia dependências sem coordenador central |
| 7 | +**Tipo**: TDD (Test-Driven Development) + SDD (Spec-Driven Development) |
| 8 | + |
| 9 | +## Arquitetura (SDD) |
| 10 | + |
| 11 | +``` |
| 12 | +┌─────────────────────────────────────────────────┐ |
| 13 | +│ Federated API Governor │ |
| 14 | +├─────────────────────────────────────────────────┤ |
| 15 | +│ Registry │ Policy Engine │ Audit Trail │ |
| 16 | +│ ───────── │ ───────────── │ ─────────── │ |
| 17 | +│ Service A │ Rate Limit:100 │ 2026-06-07T... │ |
| 18 | +│ Service B │ RBAC: admin │ 2026-06-07T... │ |
| 19 | +│ Service C │ Circuit: 3/5 │ 2026-06-07T... │ |
| 20 | +└────────────┴────────────────┴──────────────────┘ |
| 21 | + │ │ │ |
| 22 | + ▼ ▼ ▼ |
| 23 | + ┌──────────┐ ┌──────────┐ ┌──────────┐ |
| 24 | + │ Agent A │ │ Agent B │ │ Agent C │ |
| 25 | + │ (API cli)│ │ (API cli)│ │ (API cli)│ |
| 26 | + └──────────┘ └──────────┘ └──────────┘ |
| 27 | +``` |
| 28 | + |
| 29 | +### Contratos de Segurança (SDD) |
| 30 | + |
| 31 | +1. **Autenticação**: JWT com claims `agent_id`, `scope`, `ttl` |
| 32 | +2. **Autorização**: RBAC hierárquico (admin > dev > agent > readonly) |
| 33 | +3. **Rate Limiting**: Token bucket por agente, defaults: 100/min (agent), 1000/min (admin) |
| 34 | +4. **Circuit Breaker**: 3 falhas consecutivas → 30s half-open → 5 sucessos → closed |
| 35 | +5. **Audit Trail**: Log imutável de todas as chamadas (who, what, when, result) |
| 36 | +6. **Cache**: Respostas cacheadas por 60s com invalidação por evento |
| 37 | + |
| 38 | +## Casos de Teste (TDD) |
| 39 | + |
| 40 | +### CT-001: Registry — Registro de Serviço |
| 41 | +```python |
| 42 | +def test_register_service(): |
| 43 | + governor = FederatedAPIGovernor() |
| 44 | + service = APIService(name="alpha", version="1.0", endpoints=["/predict", /health"]) |
| 45 | + result = governor.register(service) |
| 46 | + assert result.status == "registered" |
| 47 | + assert governor.registry.get("alpha") == service |
| 48 | +``` |
| 49 | + |
| 50 | +### CT-002: Policy Engine — Rate Limiting por Agente |
| 51 | +```python |
| 52 | +def test_rate_limit_agent(): |
| 53 | + governor = FederatedAPIGovernor() |
| 54 | + governor.set_policy("agent-alpha", RateLimit(calls=5, window_sec=60)) |
| 55 | + for i in range(5): |
| 56 | + assert governor.check_rate_limit("agent-alpha") == True |
| 57 | + assert governor.check_rate_limit("agent-alpha") == False # exceeded |
| 58 | +``` |
| 59 | + |
| 60 | +### CT-003: Circuit Breaker — 3 Falhas → Open |
| 61 | +```python |
| 62 | +def test_circuit_breaker_trips(): |
| 63 | + governor = FederatedAPIGovernor() |
| 64 | + service = "model-serving" |
| 65 | + for _ in range(3): |
| 66 | + governor.record_failure(service) |
| 67 | + assert governor.get_circuit_state(service) == "open" |
| 68 | +``` |
| 69 | + |
| 70 | +### CT-004: Audit Trail — Imutabilidade |
| 71 | +```python |
| 72 | +def test_audit_trail_immutable(): |
| 73 | + governor = FederatedAPIGovernor() |
| 74 | + governor.call("agent-a", "service-b", "predict", {"x": 1}) |
| 75 | + governor.call("agent-b", "service-a", "health", {}) |
| 76 | + entries = governor.get_audit(limit=2) |
| 77 | + assert len(entries) == 2 |
| 78 | + assert entries[0].agent_id == "agent-b" # most recent first |
| 79 | + assert "hash" in entries[0].model_dump() |
| 80 | +``` |
| 81 | + |
| 82 | +### CT-005: Discovery — Descoberta Automática |
| 83 | +```python |
| 84 | +def test_service_discovery(): |
| 85 | + governor = FederatedAPIGovernor() |
| 86 | + governor.register(APIService(name="gamma", version="2.0")) |
| 87 | + governor.register(APIService(name="delta", version="1.5")) |
| 88 | + services = governor.discover(query="version>=2.0") |
| 89 | + assert len(services) == 1 |
| 90 | + assert services[0].name == "gamma" |
| 91 | +``` |
| 92 | + |
| 93 | +### CT-006: Federation — Propagação de Políticas entre Nós |
| 94 | +```python |
| 95 | +def test_federation_propagation(): |
| 96 | + node_a = FederatedAPIGovernor(node_id="a") |
| 97 | + node_b = FederatedAPIGovernor(node_id="b") |
| 98 | + node_a.federate_with(node_b) |
| 99 | + node_a.set_policy("global", RateLimit(calls=50, window_sec=60)) |
| 100 | + assert node_b.get_policy("global") is not None |
| 101 | +``` |
| 102 | + |
| 103 | +### CT-007: Cache — Invalidação por Evento |
| 104 | +```python |
| 105 | +def test_cache_invalidation(): |
| 106 | + governor = FederatedAPIGovernor() |
| 107 | + governor.cache_set("key:model-1", {"data": "cached"}, ttl_sec=60) |
| 108 | + assert governor.cache_get("key:model-1") is not None |
| 109 | + governor.invalidate("model-1") |
| 110 | + assert governor.cache_get("key:model-1") is None |
| 111 | +``` |
| 112 | + |
| 113 | +### CT-008: Versioning — Múltiplas Versões de API |
| 114 | +```python |
| 115 | +def test_api_versioning(): |
| 116 | + governor = FederatedAPIGovernor() |
| 117 | + governor.register(APIService(name="api", version="1.0", endpoints=["/v1/data"])) |
| 118 | + governor.register(APIService(name="api", version="2.0", endpoints=["/v2/data"])) |
| 119 | + v1 = governor.resolve("api", version="1.0") |
| 120 | + v2 = governor.resolve("api", version="2.0") |
| 121 | + assert v1.endpoints == ["/v1/data"] |
| 122 | + assert v2.endpoints == ["/v2/data"] |
| 123 | +``` |
| 124 | + |
| 125 | +## Critérios de Aceitação |
| 126 | + |
| 127 | +- [ ] 8/8 CTs aprovados (RED → GREEN) |
| 128 | +- [ ] Cobertura mínima: 85% (pytest-cov) |
| 129 | +- [ ] Audit trail com hash SHA-256 (imutabilidade) |
| 130 | +- [ ] Performance: < 5ms overhead por chamada governada |
| 131 | +- [ ] Documentação dos endpoints gRPC/REST gerada |
| 132 | + |
| 133 | +## Integração com Ecossistema |
| 134 | + |
| 135 | +| Componente | Relação | Prioridade | |
| 136 | +|-----------|---------|:----------:| |
| 137 | +| Container DI | Host do governor | Alta | |
| 138 | +| MCP Servers | Registro automático | Alta | |
| 139 | +| Code GraphRAG | Descoberta de dependências | Média | |
| 140 | +| Audit Trail TSAC | Log imutável | Alta | |
0 commit comments