Context. surface customer · domain lilith · route /lilith-studio/scenes · auth signed-in + role:v1_editorial_producer (default) · source apps/oshun/web/src/app/lilith-studio/scenes/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-07-01 deep browser coverage added in apps/oshun/web/e2e/lilith-scene-editor-deep.spec.ts for every editor control, drag/drop, graph selection, provenance selection, publish readiness, real-BFF publish, draft reset, real-service-worker offline replay, and mobile standalone overflow.
Purpose#
Author Tara venue scenes — place V1 library assets, tune lighting, select a
rights-cleared sound bed, bind room interactions, simulate a 4,096-attendee
stadium load, pass color/motion/caption accessibility checks, and publish
through the V1 editorial release branch. The page
(apps/oshun/web/src/app/lilith-studio/scenes/page.tsx) returns
<TaraSceneEditor /> 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) — "Scene authoring" surface tab → "Open Scene authoring" link - Direct URL / bookmark — yes (signed-in)
Layout regions#
TaraSceneEditor
(apps/oshun/web/src/app/lilith-studio/scenes/TaraSceneEditor.tsx):
- Header: eyebrow "Lilith Studio / Scene editor", title "Tara venue
authoring", lede, two header actions — "Lilith shell" →
/lilith-studio, "V1 workflow" →/studio/review-approval-workflows - Three-column grid:
- Asset lane (
aria-label="Scene asset library"):- Panel header: "Asset tray" + "Drag assets into a venue zone or place them in the selected zone."
- Asset list — four scene assets from
TARA_SCENE_EDITOR_ASSETS: cedar-altar, lotus-canopy, lantern-path, chime-cluster — each with a draggable grip button (data-testid="lilith-scene-asset-<id>",data-lilith-scene-asset=<id>) and a "Place in selected zone" inline action button (data-lilith-scene-place-asset=<id>)
- Stage panel (
<main>):- Stage header: "Tara garden venue", selected zone label, status pill
(
data-lilith-scene-release-state) — "Draft branch" or "Release edition published" - Stage (
data-testid="lilith-scene-stage") — four zone buttons fromTARA_SCENE_EDITOR_ZONES: threshold, mandala, north-grove, sound-corner — eachdata-testid="lilith-scene-zone-<id>"with anchor, tone, and placement list ("Drop asset here" when empty) - Scene graph panel (
data-lilith-scene-graph-editor): node count / edge count summary; node button list (aria-label="Scene graph nodes",data-lilith-scene-graph-node=<id>); detail panel with selected node's scope and edges in/out
- Stage header: "Tara garden venue", selected zone label, status pill
(
- Control lane (
aria-label="Scene controls"):- Lighting (
data-lilith-scene-lighting-panel): kelvin/intensity readout; segmented buttons forTARA_SCENE_EDITOR_LIGHTING(data-lilith-scene-lighting-preset=<id>) — dawn-soft, twilight- amber, moonlit-blue - Audio (
data-lilith-scene-audio-panel): rights/loudness readout; segmented buttons for rights-clearedTARA_SCENE_EDITOR_ AUDIO(none filtered out) — forest-drone, singing-bowl, rain- texture (data-lilith-scene-audio-bed=<id>) - Interaction binder (
data-lilith-scene-interaction-binder): Trigger select (data-lilith-scene-trigger-select, optionsINTERACTION_TRIGGERS: approach-altar, touch-chimes, enter-grove), Action select (data-lilith-scene-action-select, optionsINTERACTION_ACTIONS: open-breath-primer, play-mantra-preview, dim-room), "Add binding" primary button (data-lilith-scene-add-binding), binding list (data-lilith-scene-binding-list) - Capacity and sharding (
data-lilith-scene-capacity-panel): Capacity tier segmented (TARA_SCENE_CAPACITY_TIERS: studio, salon, festival, stadium;data-lilith-scene-capacity-tier=<id>), Sharding profile segmented (TARA_SCENE_SHARDING_PROFILES: single-room, regional-fanout, interest-management;data-lilith-scene-sharding-profile=<id>), "Run 4,096 attendee simulation" primary button (data-lilith-scene-run-attendee-simulation), simulation stats<dl>(Accepted / Shards / Interest cells;data-lilith-scene-attendee-simulation,data-simulation-state) - Accessibility checker (
data-lilith-scene-accessibility- checker): color profile segmented (TARA_SCENE_COLOR_PROFILES: low-contrast-dusk, wcag-aa-cedar), motion segmented (TARA_SCENE_MOTION_PROFILES: full-sweep, comfort-reduced), caption segmented (TARA_SCENE_CAPTION_PROFILES: ambient-only, full-spatial-captions), check list perid(color / motion / caption) withdata-check-passed, remediation list
- Lighting (
- Asset lane (
- Release panel (
aria-label="Scene publish controls"):- Readiness grid: Focal asset placed / Lighting preset selected / Rights-cleared audio selected / Interaction binding added / Stadium simulation passed / Accessibility checker passed
- "Publish Tara venue" release button (
data-lilith-scene-publish) - Publish status (
data-lilith-scene-publish-status) - Publish manifest textarea (read-only,
data-lilith-scene-publish-manifest)
LilithProvenanceInspector— surface IDtara-scene-editor, assets =TARA_SCENE_PROVENANCE_ASSETS
States#
- Loading — client component; no route-local skeleton state. Browser coverage waits for the hydrated editor after the signed-in layout gate.
- Draft (default) —
publishState='draft',data-publish-readydepends on readiness flags - Asset placed —
placements.length > 0; deep coverage places all four assets and asserts the editor placement count. - Zone selected —
selectedZoneIdupdates;data-selected="true"on the zone - Asset dragged into zone — drop handler adds placement; browser test
dispatches a real
DataTransferdrag/drop fromcedar-altartomandala. - Interaction binding added — binding list grows
- Stadium tier + interest-management profile + simulation run —
data-interest-management-ready="true" - Accessibility passing —
data-accessibility-ready="true" - Publish blocked —
canPublish === false - Publish ready —
canPublish === true - Published —
data-publish-state="published"after the real/v1/admin/studio/scenes/publishBFF route returns the persisted publish id and release stream - Any change after publish — returns to draft
(
setPublishState('draft')) - Offline —
/lilith-studio/scenesis an exact service-worker shell route; focused coverage warms the realsw.jscache and replays the editor offline without shell fallback.
Interactions#
Header#
- "Lilith shell" link — href
/lilith-studio - "V1 workflow" link — href
/studio/review-approval-workflows
Asset lane#
- Each asset drag handle (4 — cedar-altar, lotus-canopy, lantern-path, chime-cluster)
- Each "Place in selected zone" inline action button
Stage / zones (4 buttons)#
- threshold zone (
data-lilith-scene-zone="threshold") - mandala zone
- north-grove zone
- sound-corner zone
- Drop handler — accepts dragged asset and calls
placeAsset(assetId, zoneId)
Scene graph#
- Each node button — sets
selectedGraphNodeId - Edge list (read-only)
Lighting#
- Three preset buttons (dawn-soft, twilight-amber, moonlit-blue)
Audio#
- Three sound-bed buttons (forest-drone, singing-bowl, rain-texture)
Interaction binder#
- Trigger select
- Action select
- "Add binding" button (primary)
- Binding list (read-only)
Capacity and sharding#
- Four capacity tier buttons (studio, salon, festival, stadium)
- Three sharding profile buttons (single-room, regional-fanout, interest-management)
- "Run 4,096 attendee simulation" button
- Function:
runAttendanceSimulation()populates accepted attendees, shard count, interest cells
- Function:
Accessibility checker#
- Two color profile buttons
- Two motion profile buttons
- Two caption profile buttons
- Check results list — per check with pass/fail
- Remediation list — empty state "Accessibility checks passed for scene publish." when none
Release panel#
- Six readiness rows — read-only
- "Publish Tara venue" release button (
data-lilith-scene-publish)- Function: POSTs to
/v1/admin/studio/scenes/publish; setspublishState='published'only after the BFF returns a publish id and release stream. - Disabled when
canPublish === false
- Function: POSTs to
- Publish manifest textarea (read-only)
Provenance inspector#
-
LilithProvenanceInspector— deep coverage asserts asset count, selects the singing-bowl audio provenance row, and verifies the bundle route contract.
Data & contracts#
- Reads: in-file constants
TARA_SCENE_EDITOR_ASSETS,TARA_SCENE_EDITOR_ZONES,TARA_SCENE_EDITOR_LIGHTING,TARA_SCENE_EDITOR_AUDIO,INTERACTION_TRIGGERS,INTERACTION_ACTIONS,TARA_SCENE_CAPACITY_TIERS,TARA_SCENE_SHARDING_PROFILES,TARA_SCENE_COLOR_PROFILES,TARA_SCENE_MOTION_PROFILES,TARA_SCENE_CAPTION_PROFILES,TARA_SCENE_PROVENANCE_ASSETS - Writes: client state for authoring edits; publish POSTs to the real
/v1/admin/studio/scenes/publishBFF route and surfaces the persistedpublishId/releaseStreamresponse. The current BFF store is the scoped V1 release-stream persistence for this route. - Realtime: none
- Caching: client bundle plus exact service-worker shell route
/lilith-studio/scenesfor warmed offline document replay - Auth/role check: proxy enforces signed-in session; the
/lilith-studio/*layout enforcesstudio:editorial/admin:*scope
Cross-references#
- Studio shell:
lilith-studio.md - Sibling editors:
lilith-studio-asana.md,lilith-studio-avatar-costume.md,lilith-studio-concerts.md,lilith-studio-music.md,lilith-studio-personas.md,lilith-studio-provenance.md - Tara hub (the consumer of published venues):
../03-tara/tara.md - Component source:
apps/oshun/web/src/app/lilith-studio/scenes/TaraSceneEditor.tsx
E2E coverage#
apps/oshun/web/e2e/lilith-scene-editor-deep.spec.ts— granular browser coverage for all header links, assets, zone selection, drag/drop, graph selection, lighting/audio controls, binding, capacity/sharding, accessibility, readiness rows, provenance selection, real-BFF publish, draft reset, real service-worker offline replay, and mobile standalone overflow.apps/oshun/web/e2e/lilith-scene-editor-smoke.spec.ts— primary Tara venue authoring/publish flow plus blocked accessibility, non-interest-management, access-denied, and shell-entry checks.apps/oshun/web/e2e/lilith-scene-publish.spec.ts— direct BFF route contract for publish/list/error cases and UI publish persistence through the route.apps/oshun/web/e2e/lilith-studio-shell-smoke.spec.ts— Lilith Studio shell route contract and/lilith-studio/scenesadvertised surface link.
Resolved questions#
- Drag-and-drop has a keyboard-accessible equivalent: each asset card has a keyboard-focusable "Place in selected zone" button, and the focused deep spec verifies all four inline placement actions.
- The stadium simulation passes only when capacity is
stadium, sharding isinterest-management, the simulated attendance is 4,096, shard count is within the profile max, at least three assets are placed, and at least one interaction binding exists. - Publish destination is traced to
/v1/admin/studio/scenes/publishand verified against the BFF publish/list contract; this is no longer a local-onlysetPublishState('published')transition.