Commit 71613323 authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

docs: QoD create is 201; REQ-OEG-05's 202 covers EAM only

UC-OOP-02 said QoD create returns 202; OEG returns 201, as the pinned
QoD contract says. The family split (QoD create 201 / delete 204, TI
create 201 / delete 202, EAM long-running 202) is now stated where
REQ-OEG-05 and platform Decision 6 describe acceptance, which closes
OEG's C30. No application code changes.

Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 3057b30a
Loading
Loading
Loading
Loading
+2 −3
Changes for oeg/requirements-and-design.md: 2 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ Each verification reference names existing tests or a required check in [§S](im
| REQ-OEG-02 | OEG must validate OAuth 2.0 Bearer JWTs issued by Keycloak (realm `oop`) and must enforce the required role and the operation's CAMARA scope on each route, for every token (ADR-0048). [Design](#i1-authentication-and-ownership); [verify: authorization/caller-context tests](implementation-and-delivery.md#s-testing). |
| REQ-OEG-03 | OEG must implement per-API-family versioning by serving each family at exactly the path its own vendored spec defines — no OOP-invented version substitution, including when the vendored spec is still `0.1.0-alpha.1` (CAMARA EAM: vendored path segment `v0.1alpha1`, e.g. `/edge-application-management/v0.1alpha1/...`). No OEG-injected platform namespace segment; OEG platform endpoints live under `/platform/v1/`. Each API family versions independently; OEG must not use a platform-wide version prefix. [Design](#i2-api-paths-and-compatibility); [verify: vendored-spec refs/conformance](implementation-and-delivery.md#s-testing). |
| REQ-OEG-04 | On the CAMARA northbound surface, OEG must return errors using CAMARA's `ErrorInfo` shape (`status`, `code`, `message`) with an `X-Correlator` response header for all client and server error responses; this is not RFC 7807 `application/problem+json`, which the vendored CAMARA spec does not define. On the operator-facing federation-lifecycle proxy endpoints (contract §5, ADR-0051), OEG must instead return OPG.04 `application/problem+json` `ProblemDetails` for every error — relaying FM's error body unchanged, and using a fixed `ProblemDetails` template for its own `400`/`401`/`403`/`502`/`503` (ADR-0050). [Design](#n1-errors-and-caller-actions); [verify: error/flow tests](implementation-and-delivery.md#s-testing). |
| REQ-OEG-05 | For long-running operations, OEG must persist an operation record in `oeg_db` with status `PENDING` under a unique internal `operationId`, publish a `command.srm.*` message on the DataBus matching `CommandEnvelopeV1` + payload schemas shared with SRM, and return HTTP 202 with the CAMARA resource body (`AppInstanceInfo` or `{appDeploymentId}`); `operationId` is exposed only via `/platform/v1/operations/{operationId}` (ADR-0005). For EAM command acceptance, OEG must commit state and command intent atomically through a transactional outbox and must obtain broker acknowledgment before returning 202 (§M.2). [Design](#j2-single-zone-deployment); [verify: EAM service/contract tests; crash gap](implementation-and-delivery.md#s-testing). |
| REQ-OEG-05 | For long-running Edge Application Management operations, OEG must persist an operation record in `oeg_db` with status `PENDING` under a unique internal `operationId`, publish a `command.srm.*` message on the DataBus matching `CommandEnvelopeV1` + payload schemas shared with SRM, and return HTTP 202 with the CAMARA resource body (`AppInstanceInfo` or `{appDeploymentId}`); `operationId` is exposed only via `/platform/v1/operations/{operationId}` (ADR-0005). For EAM command acceptance, OEG must commit state and command intent atomically through a transactional outbox and must obtain broker acknowledgment before returning 202 (§M.2). [Design](#j2-single-zone-deployment); [verify: EAM service/contract tests; crash gap](implementation-and-delivery.md#s-testing). |
| REQ-OEG-06 | OEG must consume `event.srm.operation.completed` events from the DataBus and must update the matching `operations` row to `COMPLETED`, `PARTIALLY_COMPLETED`, or `FAILED`, including error details from the payload (ADR-0005). [Design](#m1-completion-and-status); [verify: EAM/QoD/TI event tests](implementation-and-delivery.md#s-testing). |
| REQ-OEG-07 | OEG must perform idempotent publishes: the same logical request (same `operationId` or client `Idempotency-Key`) must not create duplicate `PENDING` rows or duplicate `command.srm.*` publishes. For an existing EAM `Idempotency-Key` reused by the same provider with a non-equivalent request, OEG must return 409 (§M.3). [Design](#m3-idempotency-and-concurrency); [verify: idempotency tests; replica/crash gap](implementation-and-delivery.md#s-testing). |
| REQ-OEG-08 | When a request carries `subscriptionRequest.sink`, OEG must deliver status-change notifications as CloudEvents (`application/cloudevents+json`) per the vendored CAMARA EAM spec on terminal operation state, authenticating to the sink with `Authorization: Bearer` using the registered `sinkCredential` (ADR-0008), stored encrypted at rest; a delivery whose token has expired or been revoked is skipped, never sent unauthenticated (ADR-0063). `operationId` is never included in callback payloads. [Design](#m4-callbacks); [verify: callback/secrets tests; retry gap](implementation-and-delivery.md#s-testing). |
@@ -37,7 +37,7 @@ Each verification reference names existing tests or a required check in [§S](im
| REQ-OEG-16 | OEG must persist enough context in `api_usage_records` and operation metadata to support IEC/PEC models downstream (record app id, API product id, timestamp; real-time CHF — 3GPP convergent charging function, see [platform/future-architecture.md](/platform/future-architecture.md) — is future scope without an assigned release). IEC/PEC are not otherwise defined in this repo; confirm exact meaning with the charging domain owner before implementation. [Design](#i3-policy-and-nonfunctional-targets); [verify: charging/metering verification missing](implementation-and-delivery.md#s-testing). |
| REQ-OEG-17 | OEG must provide the eight outbound federation lifecycle operations, partner registration/read/update and identity read in [contract §5](interface-contract.md#5-federation-relay). It must relay raw bodies, query strings and responses byte-for-byte over synchronous internal HTTP, protected by cluster network policy without a dedicated credential. It must require operator authorization, retain no operations/federation state or bodies, execute no EWBI protocol and make no deployment-locality decision. Inbound EWBI belongs to FM. [Design](#k4-operator-federation-relay); [verify: FM client/GSMA tests; raw-query/policy gap](implementation-and-delivery.md#s-testing). |

**Acceptance-status scope conflict C30:** REQ-OEG-05 states a generic 202 for long-running work using EAM resource examples. Pinned QoD/TI creation contracts use 201, and asynchronous QoD deletion uses 204. Their family-specific responses remain authoritative examples here; the scope/wording of the generic requirement needs clarification. Their wire contracts remain unchanged pending that clarification.
**Acceptance status per family.** REQ-OEG-05's 202 applies to Edge Application Management. QoD and Traffic Influence are also fulfilled asynchronously but keep the status codes of their pinned contracts: QoD create 201 and delete 204, Traffic Influence create 201 and delete 202 ([contract §11](interface-contract.md#11-network-api-contracts)).

## I. Exposure, Security and Policy

@@ -349,7 +349,6 @@ Specification links identify the current rule or open question. Code evidence re
| **C26** Deployment readiness and operating policies | [Delivery §P–Q](implementation-and-delivery.md#q-build-and-deployment); [§T–U](implementation-and-delivery.md#t-known-gaps) | OEG core/config.py, Dockerfile, CI; Helm OEG values/templates at selected commits | Production resource sizing, migration/rollback, backup and recovery policies are not established by these implementation defaults. | Define production resources, TLS/ingress, migration/rollback, backup, RPO/RTO and accountable operator; do not assume unmeasured sizing or acceptance. |
| **C27** Correlation is an opaque string of up to 256 characters, but stored in 128 | Vendored CAMARA common XCorrelator; [contract §1](interface-contract.md#correlation-string-boundary), [§9](interface-contract.md#9-data-dictionary) | OEG api/camara/common.py:7–12; api/error_handlers.py:35–52; adapters/database/sql.py:113 | Header validation and storage lengths disagree; generated UUIDs fit, but accepted 129–256-character caller values may fail persistence. Exact response/escaped side effects were not tested. | Align external validation, storage and migration without silent truncation; decide/verify async failure behaviour. |
| **C28** Combined CPU/GPU resource totals sum; topology merge is not defined | [§J.1](#j1-registration); [contract §6](interface-contract.md#combined-pools-and-topology-limits); [ADR-0019](/decisions/0019-gpu-accelerator-units-fixed-not-camara-sourced.md) | OEG application/mappers/edge_application_mapper.py:563–608; GPU-only mapper tests:776–824 | Selected GPU values overwrite CPU/memory instead of summing. CPU topology wins when present, GPU topology supplies minima otherwise; GPU minimum memory is appended. No agreed combined-topology precedence is established. | Preserve required totals and fix or resolve the implementation mismatch. Decide topology precedence and add combined/GPU-only verification. |
| **C30** Every long-running acceptance returns 202 versus family-specific responses | REQ-OEG-05; pinned QoD/TI OpenAPI create/delete responses; [contract §11](interface-contract.md#11-network-api-contracts) | OEG selected QoD router:66–130 (create201/delete204); TI router create201/delete202 | Applying the generic 202 statement to every async family would violate their documented wire responses. | Clarify REQ-OEG-05 scope while preserving family-specific wire contracts. |

Remaining operational choices include retention/purge, schema evolution/rollback, key rotation/backup, outage budgets and RPO/RTO. Their owners and acceptance are Unspecified. Shared documents additionally conflict on health/helpers, SRM region/seed/expiry and FM's query/trust. ADR-0030 governs CAMARA ErrorInfo; ADR-0009 includes an RFC 7807 illustration. ADR-0006/0048 also contain identity/helper/scope disagreements; the applicable evidence is identified above. Portal does not forward `Idempotency-Key`; safe client retries through it need follow-up. Each requires the identified contract or implementation resolution.

+2 −2
Changes for platform/architecture.md: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -270,7 +270,7 @@ An app developer wants to establish a Quality of Service session for a device (e
1. **OEG:** Validates JWT, role, request body (device, QoS profile, duration, sink).
2. **OEG:** Derives `app_provider_id` from token. Resolves QoS profile to internal reference. Normalizes payload into `NetworkCapabilityPayloadV1`.
3. **OEG:** Writes operation (PENDING). Publishes `command.srm.network.capability.activate` with `capability_type=qod_session`.
4. **OEG → App Provider:** Returns `202 Accepted`.
4. **OEG → App Provider:** Returns `201 Created` with the session (`qosStatus: REQUESTED`); fulfilment is still asynchronous.
5. **SRM:** Writes `service_order` (`order_type=activate_capability`, `target_service_instance_id` NULL). Resolves the network domain and `control_path_binding`. Creates `service_instance` in the selected zone (session runtime root).
6. **SRM → TF-SDK:** Calls the network adapter to activate the capability.
7. **TF-SDK:** Validates normalized payload. Runs vendor-specific validation (e.g., OAI requires IPv4). Builds 3GPP `AsSessionWithQoSSubscription`. Enriches with vendor params (DNN, S-NSSAI, flow descriptors). Sends `POST` to NEF.
@@ -552,7 +552,7 @@ These decisions are **binding** — they have been made and should not be reopen

**Why:** Deployment and network capability provisioning involve multi-step orchestration that can take seconds to minutes. Forcing these into synchronous HTTP would block connections and waste resources. Real-time queries like device location need sub-second responses and should not pay the cost of queueing and persistence.

**Practical meaning:** Async operations return `202 Accepted` with the CAMARA resource body (e.g. `AppInstanceInfo` or `{appDeploymentId}`) (ADR-0005). The operation row in `oeg_db` is required. `GET /platform/v1/operations/{operationId}` is the intended read and is not mounted; who may call it is open ([OEG gap register](/oeg/requirements-and-design.md#n3-disagreements-and-decision-register), [OEG interface contract §1](/oeg/interface-contract.md#1-api-surfaces-and-errors)). The result arrives via `event.srm.operation.completed` on the DataBus (and optionally via CloudEvent callback to the registered sink, ADR-0008). Sync queries return `200` with the result inline.
**Practical meaning:** Async Edge Application Management operations return `202 Accepted` with the CAMARA resource body (e.g. `AppInstanceInfo` or `{appDeploymentId}`) (ADR-0005). QoD and Traffic Influence keep their pinned status codes: create `201`, QoD delete `204`, Traffic Influence delete `202`. The operation row in `oeg_db` is required. `GET /platform/v1/operations/{operationId}` is the intended read and is not mounted; who may call it is open ([OEG gap register](/oeg/requirements-and-design.md#n3-disagreements-and-decision-register), [OEG interface contract §1](/oeg/interface-contract.md#1-api-surfaces-and-errors)). The result arrives via `event.srm.operation.completed` on the DataBus (and optionally via CloudEvent callback to the registered sink, ADR-0008). Sync queries return `200` with the result inline.

---