Context. surface customer · domain lilith · route /lilith-studio/provenance · auth signed-in + role:v1_editorial_producer (default) · source apps/oshun/web/src/app/lilith-studio/provenance/page.tsx
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
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 IDprovenance-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'srelease.auditChainarray
- Header strip: kicker "Studio provenance hub", subtitle "One-click provenance
view", count badge
States#
- Hydrated route — client component reaches
data-hydrated="true"after mount in the real browser - Default selection — first asset
(
LILITH_STUDIO_SHELL_PROVENANCE_ASSETS[0]) — scene-authoring - Asset selected —
selectedAssetIdupdates; detail panel + bundle JSON reflect the new asset - No assets — shared inspector returns
null; covered byLilithProvenanceInspector.test.tsxbecause the hub route always supplies 8 assets - Offline — pure client view; works offline
Interactions#
Asset toolbar (8 buttons, one per V3 surface)#
- Each "Provenance /
- Function:
setSelectedAssetId(asset.id) - Screen reader:
aria-label="Open provenance asset <id>" aria-pressedreflects selection
- Function:
Detail panel#
- 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) - Evidence list — bullet list per asset; the automated hub matrix checks every selected asset's evidence count and representative evidence text
- Bundle JSON readout — read-only; its
release.auditChainarray is the only surface that renders the audit chainsource-lane → authoring-surface → editorial-candidate → release-edition
Data & contracts#
- Reads:
LILITH_STUDIO_SHELL_PROVENANCE_ASSETSfromapps/oshun/web/src/app/lilith-studio/LilithStudioShell.tsx(derived fromLILITH_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— 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-avatar-costume.md,lilith-studio-concerts.md,lilith-studio-music.md,lilith-studio-personas.md,lilith-studio-scenes.md - Component sources:
apps/oshun/web/src/app/lilith-studio/provenance/LilithStudioProvenanceHub.tsxapps/oshun/web/src/app/lilith-studio/LilithProvenanceInspector.tsxapps/oshun/web/src/app/lilith-studio/LilithStudioShell.tsx
- E2E/unit evidence:
apps/oshun/web/e2e/lilith-provenance-inspector-smoke.spec.tsapps/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
- 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