---
path: /studio/aja/ground-truth-comparison
surface: studio
domain: aja
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/aja/ground-truth-comparison/page.tsx
status: walked + e2e-covered
last_walked:
  '2026-07-02 quality-metrics-lane console addendum — Playwright real-dev-infra
  coverage now proves signed-in render, route-map contract, quick-action href
  order, ready comparison catalog/form, 44 px submit target, client joint-count
  guard with no POST, real BFF reconstruction-error result, fail-closed
  loading/unauthorized/malformed-catalog states, mobile no-overflow, and direct
  BFF 401/403/400/200 gates. Spec:
  apps/oshun/web/e2e/studio-aja-quality-metrics-lane-consoles.spec.ts.'
  '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 Ground Truth Comparison

## Purpose

Admin lane console wired to the real `@aja/motion-validation`
reconstruction-error suite via `/v1/admin/aja/ground-truth-comparison`: compare
a predicted pose against ground truth with MPJPE (raw mean per-joint error),
N-MPJPE (scale-normalized), and PCK (per-threshold keypoint accuracy + AUC). The
operator enters a joint set plus two single-frame poses.

## Entry points

- **Direct URL** — `/studio/aja/ground-truth-comparison` (signed-in + studio
  entitlement)
- **Sibling quick-actions from this page** — Perceptual Quality Metrics, Back to
  Studio

## Layout regions

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

- **Workspace panel** (`data-aja-ground-truth-comparison-workspace`):
  - `<h1>` "Aja Ground Truth Comparison Workspace" (via `WorkspaceHeading`)
  - `<p data-aja-ground-truth-comparison-summary>` — "Compare a predicted pose
    against ground truth with the real reconstruction-error suite — MPJPE,
    scale-normalized N-MPJPE, and PCK keypoint accuracy."
  - `data-aja-gtc-metrics` (metrics + PCK thresholds) + the compare form
- **Route Map panel** (`data-aja-ground-truth-comparison-route-map`): `<h2>`
  "Route Map" + one `<article>` per
  `STUDIO_AJA_GROUND_TRUTH_COMPARISON_ROUTE_MAP` entry (5 entries)
- **Quick actions panel**: `.quickAction` `<Link>`s — see Interactions

## States

- [x] **Loading** — `data-aja-gtc-loading` "Loading comparison metrics…"
- [x] **Unauthorized** — on 401/403, `data-aja-gtc-unauthorized` ("Access
      restricted." + reason, default "Aja workspace scope required to view
      ground-truth comparison.")
- [x] **Error** — non-OK / malformed / unreachable → `data-aja-gtc-error`
- [x] **Ready (form)** — catalog present: `data-aja-gtc-metrics` + the compare
      form
- [x] **Result** — `data-aja-gtc-result` with `data-aja-gtc-mpjpe`,
      `data-aja-gtc-nmpjpe`, `data-aja-gtc-pck-auc`, and a `data-aja-gtc-pck`
      row per PCK threshold
- [x] **Validation error** — `data-aja-gtc-compare-error` (e.g. "At least 3
      joints are required for stable comparison metrics." / "Each pose must
      provide one x,y,z triple per joint.")

## Interactions

### Compare form (`data-aja-gtc-compare-form`)

- [x] **Joints (comma-separated names)** — `input data-aja-gtc-field-joints`
- [x] **Ground truth ("x,y,z | x,y,z | …")** — `input data-aja-gtc-field-gt`
- [x] **Predicted ("x,y,z | x,y,z | …")** — `input data-aja-gtc-field-pred`
- [x] **Compare** — `button data-aja-gtc-compare-submit`; builds single-frame
      poses from the joint set, then sends `{ joints, predicted, groundTruth }`
      to `POST /v1/admin/aja/ground-truth-comparison/compare`

### Route Map panel (`data-aja-ground-truth-comparison-route-map`)

Non-interactive `<article>` blocks from
`STUDIO_AJA_GROUND_TRUTH_COMPARISON_ROUTE_MAP` (5 entries):
`/studio/aja/ground-truth-comparison` plus `…/scenes/[sceneId]`,
`…/exports/[exportId]`, `…/revisions/[revisionId]`, `…/governance/[policyId]`.

### Quick actions panel

- [x] **Open Aja Perceptual Quality Metrics workspace** →
      `/studio/aja/perceptual-quality-metrics`
- [x] **Back to Studio workspace index** → `/studio`

## E2E coverage

- [`apps/oshun/web/e2e/studio-aja-quality-metrics-lane-consoles.spec.ts`](../../../../apps/oshun/web/e2e/studio-aja-quality-metrics-lane-consoles.spec.ts)
  covers signed-in shell render, 5 route-map entries, exact quick-action hrefs,
  ready metrics/PCK-threshold catalog, 44 px submit target, fewer-than-3-joints
  client guard with no POST, real BFF 0.1 m reconstruction-error result with PCK
  AUC 0, loading / unauthorized / malformed-catalog fail-closed states, mobile
  no-overflow, and direct BFF auth/schema/happy-path gates.

## Data & contracts

- **Reads**: `GET /v1/admin/aja/ground-truth-comparison` (catalog: `metrics`,
  `pckThresholds`) on mount via `buildBffAuthHeaders()`, `cache: 'no-store'`
- **Writes**: `POST …/compare` → `{ comparison }` (jointCount, frameCount,
  mpjpe, nMpjpe, pck, pckAuc)
- **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 is signed-in + studio (proxy gate)

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioAjaGroundTruthComparisonWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioAjaGroundTruthComparisonRouteMap.ts`
- Sibling from quick-actions: `/studio/aja/perceptual-quality-metrics`

## Known downstream boundaries

- Route-map sub-routes are descriptive contracts; implementation status of those
  child pages is tracked separately from this leaf console.
- The signed-in/studio entitlement proxy gate is shared across `/studio/aja/*`
  and is verified outside this leaf-lane spec.
