Changes for ai2/overview-and-architecture.md: 2 added lines, 2 removed lines.
Original line number
Diff line number
Diff line
@@ -75,7 +75,7 @@ AI² is the platform's AI component.
| Shape | Two services, the agent and the MCP server, plus an optional Redis | — |
| Who decides access | OEG, from the scopes in the caller's token. AI² adds no rules of its own | [ADR-0048](/decisions/0048-platform-roles.md) |
| Credentials | No OEG credentials of its own: the portal adds the user's token and AI² passes it on. AI²'s only secret is the Groq API key | [portal/overview-and-architecture.md §D](/portal/overview-and-architecture.md) |
| What tools may call | OEG's public CAMARA APIs only | [platform/architecture.md §Agentic AI Integration](/platform/architecture.md) |
| What tools may call | OEG's public CAMARA APIs only | [platform/future-architecture.md §4](/platform/future-architecture.md#4-ai-agents-how-they-fit) |
| LLM | Groq's hosted API, chosen by `GROQ_MODEL_NAME`. Which providers and models are allowed is open (F3) | — |
| Memory | Optional, in Redis, keyed by the conversation's `session_id` | [requirements-and-design.md §L](/ai2/requirements-and-design.md) |
| Not part of AI² | Federation, direct SRM or FM calls, a database, an `ai-agent` role | [ADR-0048](/decisions/0048-platform-roles.md) |
@@ -155,7 +155,7 @@ Groq is outside the platform, so this data leaves it (F3).
In the platform chart only the agent may connect to it; Docker Compose publishes it on the host.
**Future agents.** Enterprise agents over A2A and operator automation agents are future work in
[platform/architecture.md §Agentic AI Integration](/platform/architecture.md). None is built.
[platform/future-architecture.md §4](/platform/future-architecture.md#4-ai-agents-how-they-fit). None is built.
| REQ-AI2-01 | [portal §D](/portal/overview-and-architecture.md), [ADR-0064](/decisions/0064-portal-is-one-container-with-a-thin-backend.md) | §K.2, §M.1 | `test_forward_request_bearer_token`, `test_every_tool_requires_auth_before_http`. Agent-to-MCP header forwarding: no test | Implemented |
| REQ-AI2-02 | [platform §Agentic AI Integration](/platform/architecture.md) | §K.1 | `test_tool_wire_contract` checks each tool's method and OEG path | Implemented |
| REQ-AI2-03 | [platform §Agentic AI Integration](/platform/architecture.md), [ADR-0048](/decisions/0048-platform-roles.md) | §K.3, §M.2 | None in AI²; depends on OEG's scope checks (overview E2) | Partly met: tool calls go through OEG, but session memory can show one user's earlier results to another (F4) |
| REQ-AI2-03 | [platform future architecture §4](/platform/future-architecture.md#4-ai-agents-how-they-fit), [ADR-0048](/decisions/0048-platform-roles.md) | §K.3, §M.2 | None in AI²; depends on OEG's scope checks (overview E2) | Partly met: tool calls go through OEG, but session memory can show one user's earlier results to another (F4) |
| REQ-AI2-04 | [portal §K](/portal/requirements-and-design.md), REQ-PORTAL-09 | §I.1, [contract §1](/ai2/interface-contract.md) | `test_groq_query_missing_query_returns_400`. No shared contract test with the portal | Implemented |
| REQ-AI2-05 | [ADR-0048](/decisions/0048-platform-roles.md) decision 8 (login off for the whole platform), [portal §J.5](/portal/requirements-and-design.md) | §M.1 | `test_no_token_needed_when_auth_disabled`, `test_groq_query_without_authorization_when_auth_disabled` | Implemented |
*[ADR-0022](0022-nats-jetstream-async-messaging.md) and [ADR-0025](0025-per-component-database-isolation.md) (bus and databases)
*[ADR-0048](0048-platform-roles.md) (roles) and [ADR-0060](0060-tfsdk-is-distributed-as-openop-tfsdk.md) (package name)
*[ADR-0051](0051-oeg-fronts-federation-lifecycle-ewbi-byte-for-byte.md) and [ADR-0053](0053-srm-fm-federated-lifecycle-handoff-over-the-databus.md) (federation relay and the SRM hand-off)
The list below is the full set.
*[ADR-0001](0001-srm-command-event-subject-scheme.md) - SRM DataBus contract: command.srm.* / event.srm.* with versioned envelope and per-command schemas
*[ADR-0002](0002-no-stored-capacity.md) - SRM holds no stored capacity or reservations
*[ADR-0003](0003-canonical-jsonb-parameter-shapes.md) - canonical, versioned JSONB parameter shapes for SRM
**OEG implementation evidence:** the [OEG disagreement register](/oeg/requirements-and-design.md#n3-disagreements-and-decision-register) distinguishes intended contracts from selected implementation, including operations GET, native health/helpers, consent, messaging, relay query bytes and network-policy evidence. These disagreements remain unresolved.
## Mental Model
If you are new to FM, this is the simplest useful way to think about it:
-**FM is the bridge to other operators.** When a request needs capabilities on a partner operator's network — or a partner operator needs capabilities on ours — FM handles the cross-boundary routing, identity validation, and response sanitization.
-**FM terminates the East/Westbound Interface (EWBI).** The partner-facing ingress routes the whole canonical OPG.04 prefix `/operatorplatform/federation/v1/*` straight to FM — every inbound partner operation. Separately, eight GSMA operations (`CreateFederation`, `GetFederationContextId`, `GetFederationDetails`, `DeleteFederationDetails`, `GetZoneData`, `ZoneSubscribe`, `GetZoneDetails`, `ZoneUnsubscribe`; `UpdateFederation` out of scope) are also served by OEG for the *operator-triggered outbound* direction — but on **OEG's own** platform namespace, `/platform/v1/federation/partners/{partnerOpId}/federations/...`, not these canonical paths; OEG forwards the raw GSMA payload and query string byte-for-byte to FM's mirrored `/internal/*` endpoint over a synchronous internal HTTP call (RD §L.3b; ADR-0051) and FM validates, executes, and drives the outbound handshake. The two directions are on different paths entirely, not split at the ingress on a shared URL.
-**FM does not fulfill requests itself.** For OPG.04 lifecycle mutations (install/remove application and supported network-capability operations), it publishes the same `command.srm.*` commands to DataBus that OEG publishes (ADR-0001). For stateless queries (device location, device status), it calls SRM's internal HTTP endpoints synchronously. Either way, SRM handles all fulfillment identically regardless of whether the request came from OEG or FM. Federated Service API capabilities and queries are proposed; to be discussed in the next releases (UC-FM-04, UC-FM-05).
-**FM terminates the East/Westbound Interface (EWBI).** The partner-facing ingress routes the whole canonical OPG.04 prefix `/operatorplatform/federation/v1/*` straight to FM. Every inbound partner operation lands there.
-**OEG relays the operator-triggered outbound direction on its own path.** Eight GSMA operations (`CreateFederation`, `GetFederationContextId`, `GetFederationDetails`, `DeleteFederationDetails`, `GetZoneData`, `ZoneSubscribe`, `GetZoneDetails`, `ZoneUnsubscribe`; `UpdateFederation` out of scope) are served by OEG under `/platform/v1/federation/partners/{partnerOpId}/federations/...`, not on the canonical prefix.
-**The relay is byte-for-byte.** OEG forwards the raw GSMA payload and query string to FM's mirrored `/internal/*` endpoint over a synchronous internal HTTP call (RD §L.3b; ADR-0051). FM validates, executes and drives the outbound handshake.
-**The two directions use different paths.** They are not split at the ingress on a shared URL.
-**FM does not fulfill requests itself.** For OPG.04 lifecycle mutations (install/remove application and supported network-capability operations), it publishes the same `command.srm.*` commands to DataBus that OEG publishes (ADR-0001).
-**Stateless queries go to SRM over HTTP.** For device location and device status, FM calls SRM's internal HTTP endpoints synchronously. SRM handles all fulfillment the same way whether the request came from OEG or FM.
-**Federated Service API operations are proposed for a later release.** Federated Service API capabilities and queries are proposed; to be discussed in the next releases (UC-FM-04, UC-FM-05).
-**FM enforces topology hiding.** Before any response leaves the operator boundary, FM strips internal IPs, cluster names, namespace names, pod UIDs, node names, and internal trace IDs. Partner operators never see our internal infrastructure details.
-**FM manages partner relationships.** It stores partner operator profiles, federation agreements, routing rules, and shared resource catalogues in its own PostgreSQL database (`fm_db`).
-**Establishing a new federation is triggered two ways:** an operator-initiated call to one of the eight federation-lifecycle operations OEG serves for the outbound direction on its own platform namespace, which OEG proxies to FM over a synchronous internal HTTP request carrying the raw GSMA payload and query string byte-for-byte (no DataBus, no new schema, no reshaping; ADR-0051, keeping ADR-0046's transport, superseding ADR-0043's `command.fm.federation.*` transport) — or FM self-initiating from bootstrap configuration at startup (ADR-0043). Either way, FM stores the partner-issued `federationContextId`, owns all federation state, and alone executes the outbound OPG.04 handshake. (A partner OP establishing federation *with us* arrives inbound on the canonical `/operatorplatform/federation/v1/*` prefix via the partner-facing ingress straight to FM — a distinct path OEG never serves.)
-**For zone-based deployment targeting, SRM — not OEG — determines locality and hands off to FM (ADR-0044).** SRM checks its own zone inventory first, queries FM for federated zone data when the target isn't found locally, and hands the deploy to FM as `command.fm.service.deploy` over the DataBus (ADR-0053). This is an interim layer pending a future "runtime coordinator" component (see [platform/future-architecture.md](/platform/future-architecture.md) §6.1). OEG's outbound hand-off to FM (below) is now scoped to subscriber-identifier (MSISDN/IP) routing only.
-**A new federation starts in one of two ways.** Either an operator calls one of the eight lifecycle operations on OEG, which relays it to FM byte-for-byte with no DataBus, no new schema and no reshaping (ADR-0051, keeping ADR-0046's transport, superseding ADR-0043's `command.fm.federation.*` transport). Or FM starts it itself from bootstrap configuration at startup (ADR-0043).
-**FM alone owns federation state.** It stores the partner-issued `federationContextId` and alone executes the outbound OPG.04 handshake.
-**A partner establishing federation with us arrives inbound.** It uses the canonical `/operatorplatform/federation/v1/*` prefix through the partner-facing ingress straight to FM — a path OEG never serves.
-**SRM, not OEG, decides whether a deployment zone is local or federated (ADR-0044).** SRM checks its own zone inventory first and queries FM for federated zone data when the target isn't found locally.
-**SRM hands federated deploys to FM over the DataBus.** It publishes `command.fm.service.deploy` (ADR-0053). This is an interim layer pending a future "runtime coordinator" component (see [platform/future-architecture.md](/platform/future-architecture.md) §6.1).
-**OEG's outbound hand-off to FM covers subscriber routing only.** It is scoped to subscriber-identifier (MSISDN/IP) routing.
```text
Partner Operators
@@ -565,7 +571,7 @@ Per the component boundary matrix:
**The question:** OPG.02 v10.0 §4.2.2.1 mentions forwarding consent context over EWBI for subscriber-sensitive APIs. How should FM handle consent tokens in federation?
**Recommendation:** Initially, FM does not implement consent forwarding. Consent is enforced at the leading OP's OEG before the request is federated. When the CAMARA ICM spec stabilizes, FM forwards an opaque consent reference in EWBI headers. This is a cross-cutting concern with the Consent domain in TF-SDK's future architecture.
**Recommendation:** Initially, FM does not implement consent forwarding. Where and how the leading OP's OEG enforces consent is open ([OEG F2](/oeg/overview-and-architecture.md#f-open-questions)). When the CAMARA ICM spec stabilizes, FM forwards an opaque consent reference in EWBI headers. This is a cross-cutting concern with the Consent domain in TF-SDK's future architecture.
### G3. OEG → FM Hand-off for Outbound Federation (subscriber-identifier routing only)
@@ -590,3 +596,4 @@ goes through OEG at all — see G4.
| Version | Summary |
|---|---|
| 2.0 | Initial specification for OOP Release 2.0. |
| 2.0 | First-publication pass: mental-model bullets split to one idea each (rules unchanged); G2 states OEG consent enforcement as open. |