FinOps Runway Contract

Status: draft implementation note for the ops cockpit.

The FinOps tab should not make Svelte components rediscover operational meaning from raw vendor rows. The API owns the projection. UI, MCP, and future sysadmin agents should all ask the same questions against the same shapes:

  • Which resource is closest to exhaustion?
  • Is current burn above the safe monthly pace?
  • When does the projection cross the limit?
  • Which source reading produced the answer?

API shape

GET /finops/summary remains the source endpoint. It keeps the existing budgets[] rows for detail, and adds:

resourcePressure: FinOpsResourcePressure[];
runway: {
  primaryResourceId: string | null;
  weakestLinks: FinOpsWeakestLink[];
  resources: FinOpsRunwayResource[];
};

resourcePressure[] is the normalized, vendor-neutral resource model. A row represents something that can become the bottleneck: Workers requests, AI tokens, provider spend, gateway calls, Axiom ingest, or a future Railway/Koyeb metric. Rows carry usage, limit, projection, daily burn rate, safe daily pace, days-to-limit, state, risk score, reason, and source endpoint.

runway.resources[] is chart-ready. Each resource has points for the current monthly period:

  • safe: the ideal linear budget pace.
  • actual: the aggregate usage line up to today.
  • projected: the current burn-rate projection through month end.
  • limit: the monthly ceiling.

When the API lacks a usage reading or limit, it must return null values instead of invented data. Missing vendor credentials are an operator fact, not a hidden success.

Visual intent

The FinOps page should lead with two visual answers:

  1. Monthly runway chart: actual vs safe pace vs projected burn vs limit.
  2. Weakest-link radar/ranking: which constrained resource reaches trouble first.

The existing budget and service tables remain useful drilldown surfaces, but they should not be the first visual answer. They explain the reading after the operator or AI has already seen where the pressure is.

Extension rule

Adding a provider should mean adding an adapter that emits the same resource pressure contract. The dashboard should not know whether the source is Cloudflare, Axiom, OpenAI, Anthropic, Koyeb, Render, Railway, or something else.

Source: wiki/content/studies/cockpit-vision/finops-runway-contract.md