Status: Proposed — engineering direction agent-adopted; named production ratification pending
Date: 2026-09-01
Authors: Eve SOTA gap-closure task 1.2
Reviewers: pending — Metis service owner, Platform Identity owner, Security owner; Data Governance for protected data
This ADR records a real engineering decision without fabricating human approval. It is effective for implementation and CI on merge. Production activation remains blocked until the named owners ratify it. It does not ratify or supersede ADR-M0.5.
Context#
The task-1.1 source-hashed survey found three incompatible path layers: the
Metis browser calls /api/metis/v1, its Next proxy targets /api on
http://localhost:4020, the Node gateway registers only an explicit subset
below /api/v1, and the authoritative FastAPI OpenAPI declares 803 paths below
/api. The BFF's current Metis HTTP adapter instead calls /v1/metis on a
development origin at http://localhost:4601; normal reads have neither an
abort deadline nor retries. The app defaults to the partial in-process Metis
adapter.
Identity is also incompatible: Oshun access tokens are issued for oshun-bff,
while the Metis validator currently verifies neither issuer nor audience and
understands only a coarse role rather than Oshun tenant and scopes. Forwarding
the caller's bearer would therefore be both incorrect and over-broad.
Decision#
Selected: direct, versioned HTTP from the Oshun BFF to the Metis FastAPI
service. The narrow contract is eve.metis.workbench-read.v1, exposed as
explicit GET operations below /api/v1/eve/workbench-read. The BFF bypasses the
browser Next proxy and the incomplete Node gateway. It never queries Metis
PostgreSQL, filesystem ledgers, Redis, S3, SQLAlchemy models, or migrations.
| Concern | Normative decision |
|---|---|
| Transport | oshun-bff-workbench-kit-read calls metis-fastapi-service directly over HTTPS via OSHUN_METIS_API_BASE_URL. |
| Route | Explicit GET operations below /api/v1/eve/workbench-read; no catch-all and no unversioned fallback. |
| Deadline | 1000 ms per attempt, 2250 ms total, 524288 response-byte cap. |
| Retry | At most 1 retry for GET on network/timeout or 429, 502, 503, 504; fixed 250 ms delay inside the total deadline. |
| Circuit | Open after 5 consecutive transient failures for 30 s; close after 3 half-open successes. |
| Identity | Platform-issued delegated JWT, iss=oshun-auth, aud=metis-workbench-api, TTL ≤60 s, exact per-view scope, subject and tenant. |
| Degraded mode | Typed 502/503/504 failures, no-store, never empty-success, stale cache, direct store, or in-process fallback. |
Version and compatibility lane#
The URI carries the breaking major version. Every response carries
x-metis-contract-version: 1.0.0. Metis produces a canonical OpenAPI slice
containing only the admitted operations; the BFF decoder and service contract
tests pin the same slice digest. Additive changes require a minor-version bump
and passing consumer tests. Breaking schema, authorization, or meaning changes
require a new URI major with an overlap window. There is no fallback to the
moving unversioned /api contract.
This is the task-1.1 versioned compatibility exception: implementation need not wait for the whole Metis contract to remain unchanged for seven days, but the exception applies only to explicitly admitted routes under the new prefix. It registers no view by itself. A route is admitted only when all of these hold:
- explicit FastAPI route and operationId exist in the canonical OpenAPI artifact
- bearer security and exact delegated scope are declared and enforced
- the route response schema is present in the pinned Eve OpenAPI slice
- the BFF decoder and FastAPI contract tests pass for the same slice digest
- authorization, timeout, service-loss, malformed-payload, and version-mismatch controls fail loud
- the data classification is ratified for exposure or the view contains only already-public data
Identity propagation#
The BFF first authenticates and authorizes the Oshun session. Platform Identity
then issues a short-lived delegated JWT with required claims
act, aud, exp, iat, iss, jti, nbf, scope, sub, tid, audience
metis-workbench-api, actor oshun-bff, and exact scope
metis:eve:read:<view>. Metis validates the signature, issuer, audience, time
window, subject, tenant, and exact view scope again before query execution. The
verified tid claim is authoritative; an x-tenant-id header or request
parameter cannot grant or widen access and a mismatch is refused.
The browser bearer and refresh token never cross this seam. The BFF propagates
only traceparent, tracestate, x-correlation-id, x-request-id alongside the
delegated credential, and neither tokens nor secrets may be logged.
Timeouts, retries, and degraded behavior#
Each attempt is aborted at 1000 ms and the entire operation, including the single 250 ms retry delay, is capped at 2250 ms. Only idempotent GET reads retry: network errors, timeouts, and HTTP 429/502/503/504. Authentication, authorization, validation, not-found, and contract/version failures do not retry.
Timeout is 504 metis_timeout; service loss or an open circuit is
503 metis_unavailable; a malformed or wrong-version response is
502 metis_contract_violation. The kit records execution-failed. It does not
turn any failure into [], null, a fixture, stale cache, direct-store read,
or the in-process adapter.
Rejected options#
| Option | Reason |
|---|---|
direct-store |
It bypasses Metis authorization and service invariants, couples Eve to migrations and physical stores, and violates the proposed owner boundary. |
current-in-process-metis-adapter |
It is a partial Oshun member adapter with truthful empty placeholders, not the Metis workbench authority or an independently authorizing boundary. |
browser-next-proxy |
The /api/metis/v1 browser path is a client façade and forwards browser credentials; server-side Eve must not depend on a web application hop. |
metis-node-api-gateway |
The /api/v1 gateway exposes only a small explicit subset of current FastAPI paths and cannot provide a generic or implied workbench route. |
unversioned-fastapi-routes |
The current /api routes are the moving web contract; calling them directly would not create an independently versioned compatibility seam. |
Implementation gates#
| Gate | Current state | Exact condition | Owner |
|---|---|---|---|
versioned-fastapi-facade |
not-implemented |
Metis registers explicit GET routes under /api/v1/eve/workbench-read with OpenAPI operation IDs, schemas, and bearer security. | Task 1.3 |
delegated-identity |
not-implemented |
Platform Identity issues and Metis validates the down-scoped audience-bound JWT; tenant headers alone never authorize. | Task 1.3 |
bounded-bff-client |
not-implemented |
The Eve Metis adapter enforces this decision's deadlines, retry set, response cap, circuit breaker, schema decoder, and typed failures. | Task 1.3 |
direct-fastapi-service-discovery |
not-implemented |
OSHUN_METIS_API_BASE_URL resolves to the residency-correct FastAPI service origin, not port 4020, the browser proxy, or the incomplete Node gateway. | Task 1.3 |
per-view-admission |
not-implemented |
Each candidate independently passes the compatibility-exception conditions; this decision admits zero views by itself. | Task 1.3 |
These gates make current non-compliance visible. They are not assertions that the transport already exists.
Ratification and data boundary#
| Reviewer | Status |
|---|---|
| Metis service owner | pending |
| Platform Identity owner | pending |
| Security owner | pending |
| Data Governance | pending-for-protected-data |
Implementation posture is effective-on-merge; production posture is
blocked-pending-named-ratification. ADR-M0.5 must be ratified or superseded
before protected learner, assessment, grade, integrity, or authoring records are
exposed.
Consequences#
- Metis remains the data and authorization owner; Eve consumes a versioned service contract and never becomes a second repository or migration client.
- The existing BFF domain adapter, port-4601 default, in-process default, browser proxy, and Node gateway do not satisfy this decision for Eve.
- Task 1.3 must build the narrow façade/client and independently prove each real view. Task 1.4 owns exact subject, tenant, scope, classification, and refusal controls.
- The source-hashed machine record is
../audits/eve-sota-metis-transport-decision/2026-09-01.json.
Limitations#
- This decision authorizes an implementation direction and narrow compatibility exception; it does not claim that the versioned FastAPI façade, delegated identity, or bounded BFF client already exists.
- No Metis Eve view is registered by task 1.2; task 1.3 must prove every route independently.
- Named production ratification remains pending and is not inferred from agent authorship or a merged document.
- ADR-M0.5 remains Proposed, so this decision cannot admit protected or mixed-boundary data.
- The source observations are repository evidence, not a staging or production network probe.