---
path: /studio/aja/automated-qa-pipeline
surface: studio
domain: aja
auth: signed-in + studio entitlement
source: apps/oshun/web/src/app/studio/aja/automated-qa-pipeline/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 Aja · Automated QA Pipeline

## Purpose

Admin lane console for the real `@aja/motion-validation`
`calculateTemporalConsistency` gate. The operator submits a motion's joint ids
and frames (positions per joint) plus popping/jitter thresholds; the lane scans
frame-to-frame joint displacement for "popping" (a jump past the threshold) and
the second-difference acceleration for jitter, then reads back overall, jitter,
and continuity scores and every popping transition — the release gate run before
a clip ships.

## Entry points

- **Direct URL / bookmark** — `/studio/aja/automated-qa-pipeline`; metadata
  canonical to this path
- **Studio nav** — Domain-bridge studios section of `/studio`
- **Sibling quick-actions on this page**: Ground Truth Comparison, Back to
  Studio (no breadcrumb panel on this route)
- **Operator surfacing** — see
  [`../../studio-overview.md`](../../studio-overview.md)

## Layout regions

`page.tsx` renders inside `<ShellLayout active="studio">`:

- **Workspace** (`<StudioAjaAutomatedQaPipelineWorkspace />`, archetype: LEAF
  with a capability summary):
  - `<h1>` (`WorkspaceHeading`) "Aja Automated QA Pipeline Workspace"
  - Summary `<p data-aja-automated-qa-pipeline-summary>` — typed operations,
    diagnostics, security, route map; operations lane runs the real
    temporal-consistency gate
  - **Capability Summary** panel
    (`data-aja-automated-qa-pipeline-capability-summary`, `<h2>Capability
    Summary</h2>`) — 4 `data-aja-automated-qa-pipeline-capability` cards:
    `qa-control-plane`, `diagnostics-and-trace-observability`,
    `security-permission-audit-controls`, `api-parity-and-contract-assurance`
    (descriptive copy only, no embedded sibling)
  - **Operations lane**
    (`data-aja-automated-qa-pipeline-operations-lane`, `<h2>Automated QA
    Pipeline Operations Lane</h2>`) — the live gate form (see States)
- **Route Map panel** (`data-aja-automated-qa-pipeline-route-map`): `<h2>Route
  Map</h2>` listing 5 entries from
  `STUDIO_AJA_AUTOMATED_QA_PIPELINE_ROUTE_MAP` (primary, scenes, exports,
  revisions, governance)
- **Quick-action panel**: two `Link.quickAction` anchors — Ground Truth
  Comparison, Back to Studio workspace index

## States

- [ ] **Loading** — operations lane GETs the gate catalog on mount; until it
      resolves renders `<p data-aja-qa-loading>` "Loading QA gate…"
- [ ] **Unauthorized** — 401/403 renders `data-aja-qa-unauthorized` ("Access
      restricted." + admin-scope message, default "Aja workspace scope required
      to run the QA gate.")
- [ ] **Error** — non-OK / malformed / unreachable renders `data-aja-qa-error`
      ("Could not load the QA gate." + reason)
- [ ] **Ready (form)** — success renders the catalog's checks
      (`data-aja-qa-checks` → `data-aja-qa-check-row` rows) and the
      `data-aja-qa-form`
- [ ] **Result** — a successful POST renders `data-aja-qa-result` with
      `data-aja-qa-verdict` (✓ no popping / ✗ N popping transition(s) + overall
      score), `data-aja-qa-scores` (jitter · continuity), and either
      `data-aja-qa-popping` rows (`data-aja-qa-popping-row`) or
      `data-aja-qa-no-popping`
- [ ] **Validation / assess error** — client guards (≥1 joint id; frames valid
      JSON array ≥2; thresholds positive) and POST failures render
      `data-aja-qa-assess-error`
- [x] **Empty / Standalone PWA / offline** — N/A beyond the above; shell SSR,
      lane is a client fetch on mount

## Interactions

### Operations lane (`data-aja-qa-form`)

- [ ] **Joint ids** (`data-aja-qa-joints`, text input, aria-label "joint ids",
      comma-separated)
- [ ] **Frames** (`data-aja-qa-frames`, textarea, aria-label "frames json",
      JSON array of `{ positions: { jointId: { x, y, z } } }`)
- [ ] **Popping threshold** (`data-aja-qa-popping-threshold`, input)
- [ ] **Jitter threshold** (`data-aja-qa-jitter-threshold`, input)
- [ ] **"Run temporal-consistency gate"** (`data-aja-qa-submit`, submit) — fires
      `POST /v1/admin/aja/automated-qa-pipeline/assess` with `{ joints, frames,
      poppingThreshold, jitterThreshold }`

### Capability Summary

- [ ] **Capability cards** (4 × `<article>`) — non-interactive descriptive copy

### Route Map panel

- [ ] **Route entries** (5 × `<article>`) — non-interactive path+purpose

### Quick-action panel

- [ ] **"Open Aja Ground Truth Comparison workspace"** →
      `/studio/aja/ground-truth-comparison`
- [ ] **"Back to Studio workspace index"** → `/studio`

## Data & contracts

- **Reads**: `GET /v1/admin/aja/automated-qa-pipeline` on mount — catalog
  `{ gate, checks: string[], defaultThresholds: { poppingThreshold,
  jitterThreshold } }`
- **Writes**: `POST /v1/admin/aja/automated-qa-pipeline/assess` —
  `{ joints, frames, poppingThreshold, jitterThreshold }` → `{ result }`
  (overallScore, jitterScore, continuityScore, poppingCount, popping[])
- **Realtime**: none
- **Caching**: client `fetch` on mount with `cache: 'no-store'` and
  `buildBffAuthHeaders()`; SSR shell only
- **Auth/role check**: BFF endpoints admin-scoped + fail-closed (401/403 →
  unauthorized render); route behind the signed-in + studio proxy gate

## Cross-references

- Parent: [`../../studio-overview.md`](../../studio-overview.md)
- Shell:
  [`../../../shell/04-auth-session.md`](../../../shell/04-auth-session.md)
- Sibling routes:
  [`./studio-aja-ground-truth-comparison.md`](./studio-aja-ground-truth-comparison.md)
- Component sources:
  - `apps/oshun/web/src/components/studio/StudioAjaAutomatedQaPipelineWorkspace.tsx`
  - `apps/oshun/web/src/components/studio/StudioAjaAutomatedQaPipelineRouteMap.ts`

## Open questions / known gaps

- [ ] The capability summary cards are descriptive copy only — the sole live
      surface is the temporal-consistency gate; confirm whether the other three
      capabilities (security/audit, parity) ever get their own lanes
- [ ] Route-map sub-routes are advertised but have no `page.tsx` in V1
