Disciplines · Decisions (ADRs)

ADR-0075: Eve → Metis Workbench Read Transport

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

Proposed · 2026-09-01
7sections6 minread

On this page

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.