---
path: /studio/performance-budgets
surface: studio
domain: operations
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/performance-budgets/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; live
  screen-reader, touch, offline, and telemetry-delivery checks pending a manual
  AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body
  re-derived 2026-06-03 from current source (lane-console architecture)'
---

# Studio · Performance Budgets

## Purpose

Score Web-Vitals and asset-size metrics against their upper-bound budgets with
the real performance-budget evaluator: each metric is classified within /
warning (inside a warn band below the budget) / over, reported with its budget
ratio and a signed overage percent, and rolled up into whether the overall
budget is met. The workspace (`StudioPerformanceBudgetsWorkspace`) is an admin
lane console that loads the evaluator catalog on mount and posts a budgets
payload for evaluation.

## Entry points

- **Studio root** (`/studio`) — discoverable as an operations workspace
- **Sibling quick actions** — Accessibility Governance, Experimentation and
  Feature Flags, Observability and Operational Dashboards, Metrics and Analytics
  Instrumentation, and Resilience and Error UX workspaces link in/out
- **Direct URL / bookmark** — yes

## Layout regions

`page.tsx` mounts `ShellLayout active="studio"`, renders
`StudioPerformanceBudgetsWorkspace`, then a single `panel` of 5 `quickAction`
links. There is no breadcrumb and no Route Map panel on this route.

- **Workspace heading** (`<h1>` via `WorkspaceHeading`): "Studio Performance
  Budgets"
- **Summary** (`data-performance-budgets-summary`): within / warning / over,
  signed overage percent, overall budget-met
- **Budget Evaluation Lane** (`<h2>` `data-pb-lane-heading`): the load-states +
  evaluation form + result region
- **Footer quick actions** (`panel`): 5 sibling `quickAction` links

## States

- [ ] **Loading** — `data-pb-loading` "Loading budget evaluator…" while the
      catalog request is in flight
- [ ] **Unauthorized** — `data-pb-unauthorized` "Access restricted." on a
      401/403 (admin scope required)
- [ ] **Error** — `data-pb-error` "Could not load the budget evaluator." on a
      non-OK catalog response or network failure
- [ ] **Ready (form)** — catalog loaded: `data-pb-enums` budget-status count +
      the `data-pb-form` JSON form
- [ ] **Result** — `data-pb-result` with the budget-met headline + within /
      warning / over counts and the per-metric table
- [ ] **Validation** — `data-pb-evaluate-error` for invalid JSON or a non-200
      evaluate response

## Interactions

### Budget Evaluation Lane (form)

- [ ] **Budgets JSON** (`textarea` `data-pb-payload`, `aria-label` "budgets
      json") — payload of `{ policy{ warnRatio }, metrics[{ metricId, name,
      value, budget }] }`
- [ ] **Evaluate budgets** (`button` `data-pb-submit`, `type=submit`) — POSTs
      the parsed payload to `\`${PB_ENDPOINT}/evaluate\``

### Result region

- [ ] **Headline** (`data-pb-headline`, `data-budget-met`) — Budget met /
      exceeded with `data-pb-count` within / warning / over spans
- [ ] **Metrics table** (`data-pb-metrics`) — rows `data-pb-metric-row` with
      `data-status`, cells `data-pb-metric-ratio`, `data-pb-metric-overage`,
      `data-pb-metric-status`

### Footer quick actions

- [ ] **Open Accessibility Governance workspace** →
      `/studio/accessibility-governance`
- [ ] **Back to Experimentation and Feature Flags workspace** →
      `/studio/experimentation-feature-flags`
- [ ] **Back to Observability and Operational Dashboards workspace** →
      `/studio/observability-operational-dashboards`
- [ ] **Back to Metrics and Analytics Instrumentation workspace** →
      `/studio/metrics-analytics-instrumentation`
- [ ] **Back to Resilience and Error UX workspace** → `/studio/resilience-error-ux`

## Data & contracts

- **Reads**: GET `/v1/admin/studio/performance-budgets` (catalog:
  `budgetStatuses`) on mount
- **Writes**: POST `/v1/admin/studio/performance-budgets/evaluate`
- **Realtime**: none
- **Client fetch**: `buildBffAuthHeaders()`, `cache: 'no-store'`,
  abort-on-unmount
- **Auth/role check**: admin-scoped, fail-closed (401/403 → unauthorized); route
  is signed-in + studio via the proxy gate

## Cross-references

- Parent: [`../studio-overview.md`](../studio-overview.md)
- Sibling:
  [`studio-observability-operational-dashboards.md`](./studio-observability-operational-dashboards.md),
  [`studio-metrics-analytics-instrumentation.md`](./studio-metrics-analytics-instrumentation.md),
  [`../governance/studio-accessibility-governance.md`](../governance/studio-accessibility-governance.md)
- Source:
  `apps/oshun/web/src/components/studio/StudioPerformanceBudgetsWorkspace.tsx`

## Open questions / known gaps

- [ ] Confirm the canonical metric set the evaluator scores (the default payload
      uses LCP / CLS / TBT / bundle, but the contract is caller-supplied)
- [ ] Document how the `/v1/admin/studio/performance-budgets` route wires to the
      CI budget gate, if at all
