---
path: /studio/aja/pose-estimation
surface: studio
domain: aja
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/aja/pose-estimation/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)'
---

# Aja Pose Estimation

## Purpose

Admin lane console that evaluates an estimated pose against ground truth using
the real `@aja/motion-validation` pose metrics: MPJPE (mean per-joint position
error) and PCK (percentage of correct keypoints within normalized thresholds).
`StudioAjaPoseEstimationWorkspace` loads a metric catalog from
`GET /v1/admin/aja/pose-estimation` and posts evaluations to `/evaluate`.

## Entry points

- **Direct URL** — `/studio/aja/pose-estimation` (signed-in + studio entitlement)
- **Sibling quick-actions** — reached from neighbouring Aja workspace pages whose
  quick-action panel links here
- **Sibling quick-action from this page** — "Open Aja Input Video Support
  workspace" → `/studio/aja/input-video-support`; "Back to Studio workspace
  index" → `/studio`

## Layout regions

`page.tsx` mounts `ShellLayout` with `active="studio"` and renders three panels.

- **Workspace panel** (`data-aja-pose-estimation-workspace`): owned by
  `StudioAjaPoseEstimationWorkspace`
  - `<h1>` "Aja Pose Estimation Workspace" (via `WorkspaceHeading`)
  - `<p data-aja-pose-estimation-summary>` — "Evaluate an estimated pose against
    ground truth: MPJPE (mean per-joint position error) and PCK (percentage of
    correct keypoints within normalized thresholds)."
  - The evaluate form lane (rendered once the catalog loads)
- **Route Map panel** (`data-aja-pose-estimation-route-map`): `<h2>` "Route Map"
  + one `<article>` per `STUDIO_AJA_POSE_ESTIMATION_ROUTE_MAP` entry (5 entries)
- **Quick actions panel**: `.quickAction` `<Link>`s — see Interactions

## States

- [ ] **Loading** — before the catalog resolves, `data-aja-pose-loading`
      "Loading pose metrics…"
- [ ] **Unauthorized** — on 401/403 the GET renders `data-aja-pose-unauthorized`
      ("Access restricted." + admin-scope reason, default "Aja workspace scope
      required to view pose estimation.")
- [ ] **Error** — non-OK / malformed / unreachable renders
      `data-aja-pose-error` ("Could not load pose estimation." + reason)
- [ ] **Ready (form)** — catalog present: `data-aja-pose-metrics` lists metrics +
      PCK thresholds, then `data-aja-pose-evaluate-form`
- [ ] **Result** — on a 200 evaluate, `data-aja-pose-result` shows
      `data-aja-pose-mpjpe` (MPJPE mean) and `data-aja-pose-pck-auc` (PCK AUC)
- [ ] **Validation error** — non-JSON predicted/ground-truth frames set
      `data-aja-pose-evaluate-error` "Predicted and ground-truth frames must be
      valid JSON."

## Interactions

### Evaluate form (`data-aja-pose-evaluate-form`)

- [ ] **Joints (comma-separated)** — `input data-aja-pose-field-joints`
- [ ] **Predicted frames (JSON)** — `textarea data-aja-pose-field-predicted`
- [ ] **Ground-truth frames (JSON)** — `textarea data-aja-pose-field-groundtruth`
- [ ] **Evaluate** — `button data-aja-pose-evaluate-submit`; parses both frame
      JSON blobs + splits joints, then `POST /v1/admin/aja/pose-estimation/evaluate`
      with `{ joints, predicted, groundTruth }`

### Route Map panel (`data-aja-pose-estimation-route-map`)

Non-interactive `<article>` blocks (`<strong>` path + description) from
`STUDIO_AJA_POSE_ESTIMATION_ROUTE_MAP` (5 entries): `/studio/aja/pose-estimation`
plus `…/scenes/[sceneId]`, `…/exports/[exportId]`, `…/revisions/[revisionId]`,
`…/governance/[policyId]`.

### Quick actions panel

- [ ] **Open Aja Input Video Support workspace** → `/studio/aja/input-video-support`
- [ ] **Back to Studio workspace index** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/aja/pose-estimation` (metric catalog: `metrics`,
  `pckThresholds`) on mount via `buildBffAuthHeaders()`, `cache: 'no-store'`
- **Writes**: `POST /v1/admin/aja/pose-estimation/evaluate` → `{ mpjpe, pck }`
- **Realtime**: none
- **Caching**: client fetch on mount (no-store); SSR shell only
- **Auth**: BFF endpoints admin-scoped + fail-closed (401/403 → unauthorized
  render); the route itself is signed-in + studio (proxy gate)

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioAjaPoseEstimationWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioAjaPoseEstimationRouteMap.ts`
- Embedded by aggregator:
  `apps/oshun/web/src/components/studio/StudioAjaSvcMotionAiWorkspace.tsx`
  (Pose Estimation Lane)
- Sibling from quick-actions: `/studio/aja/input-video-support`

## Open questions / known gaps

- [ ] Route-map articles are descriptive only (not links); confirm whether the
      sub-routes (`scenes`/`exports`/`revisions`/`governance`) are implemented
- [ ] Document the exact studio entitlement / proxy gate governing `/studio/aja/*`
