---
path: /lilith-studio/provenance
surface: customer
domain: lilith
auth: signed-in + role:v1_editorial_producer (default)
source: apps/oshun/web/src/app/lilith-studio/provenance/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;
  content re-verified 2026-06-03 against current source

  2026-06-28 focused automated Playwright + component walk — hub access,
  hydration, default first-asset selection, all 8 provenance buttons,
  aria-pressed transitions, selected detail metadata, evidence list counts,
  bundle JSON schema/source/release audit chain, and no-assets null render
  verified. Evidence:
  apps/oshun/web/e2e/lilith-provenance-inspector-smoke.spec.ts;
  apps/oshun/web/src/app/lilith-studio/LilithProvenanceInspector.test.tsx'
---

# Lilith Studio · Studio provenance hub

## Purpose

Inspect the V3 surface provenance records that gate Studio release-candidate
promotion. Reuses the shell's `LILITH_STUDIO_SHELL_PROVENANCE_ASSETS` list (all
8 V3 authoring surfaces) inside the `LilithProvenanceInspector` to give a single
one-click provenance view across the studio. The page
(`apps/oshun/web/src/app/lilith-studio/provenance/page.tsx`) returns
`<LilithStudioProvenanceHub />` directly; the `<ShellLayout active="studio">`
wrapper and the editorial scope gate are supplied by the route's
`apps/oshun/web/src/app/lilith-studio/layout.tsx`.

## Entry points

- **Lilith Studio shell** (`/lilith-studio`) — "Provenance inspector" surface
  tab → "Open Provenance inspector" link
- **From every other Lilith Studio sub-route** — each editor mounts its own
  inline `LilithProvenanceInspector`; the hub is the cross-surface view
- **Direct URL / bookmark** — yes (signed-in)

## Layout regions

`LilithStudioProvenanceHub`
(`apps/oshun/web/src/app/lilith-studio/provenance/LilithStudioProvenanceHub.tsx`)
is a thin wrapper.

- **Header**: eyebrow "Lilith Studio / Provenance inspector",
  `<h1>Studio provenance hub</h1>`, lede "Inspect the V3 surface provenance
  records that gate Studio release-candidate promotion."
- **`LilithProvenanceInspector`** (full surface) — surface ID `provenance-hub`,
  title "Studio provenance hub", assets =
  `LILITH_STUDIO_SHELL_PROVENANCE_ASSETS` (all 8 V3 surfaces from the shell)
  - Header strip: kicker "Studio provenance hub", subtitle "One-click provenance
    view", count badge `<N> assets`
  - Asset toolbar (`role="toolbar"`) — one button per asset
    (`aria-label="Open provenance asset <id>"`, `aria-pressed`,
    `data-lilith-provenance-open=<provenanceId>`,
    `data-testid="lilith-provenance-open-provenance-hub-<safeId>"`)
  - Detail panel — kind, label, release state, and a `<dl>`
    (`LilithProvenanceInspector.tsx`) of just three rows: Provenance ID, Source
    lane, Route; followed by the evidence list. The audit chain is **not**
    rendered here.
  - Bundle JSON readout (`buildLilithProvenanceBundle` ~41) — this is the only
    place the audit chain
    (`source-lane → authoring-surface → editorial-candidate → release-edition`)
    appears, inside the bundle's `release.auditChain` array

## States

- [x] **Hydrated route** — client component reaches `data-hydrated="true"` after
      mount in the real browser
- [x] **Default selection** — first asset
      (`LILITH_STUDIO_SHELL_PROVENANCE_ASSETS[0]`) — scene-authoring
- [x] **Asset selected** — `selectedAssetId` updates; detail panel + bundle JSON
      reflect the new asset
- [x] **No assets** — shared inspector returns `null`; covered by
      `LilithProvenanceInspector.test.tsx` because the hub route always supplies
      8 assets
- [ ] **Offline** — pure client view; works offline

## Interactions

### Asset toolbar (8 buttons, one per V3 surface)

- [x] **Each "Provenance / <label>" button**
  - Function: `setSelectedAssetId(asset.id)`
  - Screen reader: `aria-label="Open provenance asset <id>"`
  - `aria-pressed` reflects selection

### Detail panel

- [x] **Asset metadata** — read-only; the detail `<dl>` shows only provenance
      ID, source lane, and route (kind, label, and release state sit in the
      detail header above it)
- [x] **Evidence list** — bullet list per asset; the automated hub matrix checks
      every selected asset's evidence count and representative evidence text
- [x] **Bundle JSON readout** — read-only; its `release.auditChain` array is the
      only surface that renders the audit chain
      `source-lane → authoring-surface → editorial-candidate → release-edition`

## Data & contracts

- **Reads**: `LILITH_STUDIO_SHELL_PROVENANCE_ASSETS` from
  `apps/oshun/web/src/app/lilith-studio/LilithStudioShell.tsx` (derived from
  `LILITH_STUDIO_V3_AUTHORING_SURFACES`)
- **Writes**: none
- **Realtime**: none
- **Caching**: client bundle
- **Auth/role check**: the editorial scope gate lives in
  `apps/oshun/web/src/app/lilith-studio/layout.tsx` (`hasLilithStudioAccess()` →
  `admin:*`/`studio:editorial`), which wraps this route and renders
  `<LilithStudioAccessDenied />` for non-editorial roles

## Cross-references

- Studio shell: [`lilith-studio.md`](./lilith-studio.md) — the hub is the
  centralised version of the per-surface inspectors mounted on every sibling
  editor
- Sibling editors (each mounts an inline `LilithProvenanceInspector`):
  [`lilith-studio-asana.md`](./lilith-studio-asana.md),
  [`lilith-studio-avatar-costume.md`](./lilith-studio-avatar-costume.md),
  [`lilith-studio-concerts.md`](./lilith-studio-concerts.md),
  [`lilith-studio-music.md`](./lilith-studio-music.md),
  [`lilith-studio-personas.md`](./lilith-studio-personas.md),
  [`lilith-studio-scenes.md`](./lilith-studio-scenes.md)
- Component sources:
  - `apps/oshun/web/src/app/lilith-studio/provenance/LilithStudioProvenanceHub.tsx`
  - `apps/oshun/web/src/app/lilith-studio/LilithProvenanceInspector.tsx`
  - `apps/oshun/web/src/app/lilith-studio/LilithStudioShell.tsx`
- E2E/unit evidence:
  - `apps/oshun/web/e2e/lilith-provenance-inspector-smoke.spec.ts`
  - `apps/oshun/web/src/app/lilith-studio/LilithProvenanceInspector.test.tsx`

## Open questions / known gaps

- [ ] Confirm whether the hub needs to also surface non-V3 (V1 Studio)
      provenance assets — currently it shows only the V3 authoring surfaces
- [x] Document current bundle affordance — it is a read-only textarea-style JSON
      readout with no copy/export action; E2E verifies the value and component
      source confirms no clipboard affordance
- [ ] Verify whether audit-chain entries resolve to live release records or are
      descriptive strings only
