---
path: /studio/generation/living-scene
surface: studio
domain: generation
auth: anon (explicit public route)
source: apps/oshun/web/src/app/studio/generation/living-scene/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'
---

# Studio · Generation · Living Scene

## Purpose

Approved Living Scene generation surface (§24.10). The route is explicitly
public (middleware adds `/studio/generation/living-scene` to `PUBLIC_PATHS`) but
enforces tier and tenant policy inside the page and the
`@yemaya/living-scenes-runtime` library, so only approved templates and frozen
workflow classes are exposed.

## Entry points

- **Direct URL / bookmark** — yes (public)
- **Studio root** — quick action to Compose; Living Scene is also exposed on the
  Studio root once entitled
- **Deep link** with `x-oshun-tier` / `x-oshun-living-scene-templates` /
  `x-oshun-living-scene-frozen-workflow-classes` / `x-oshun-locale` headers
  (forwarded by upstream surfaces)

## Layout regions

The page is server-rendered. It reads the request headers (`tier`,
`tenantPolicy`, `requestedLocale`) via `next/headers`, then renders:

- **Outer `<main>`** with `data-living-scene-route`,
  `data-living-scene-route-entitlement-gate="route"`, dark backdrop
- **Centered column** with a single `LivingSceneCard` component receiving the
  `accessContext` ({ tier, tenantPolicy, requestedLocale })

The `LivingSceneCard` component (≈ 660 LOC) renders the Living Scene preview,
control set, and tenant-policy banner. Walk that component in a dedicated
sub-file if it becomes its own route.

## States

- [ ] **Anonymous user, no tier header** — `tier` defaults to `free`;
      `tenantPolicy.enabled` defaults to `true`; Living Scene renders for
      anonymous viewers with free-tier limits
- [ ] **`x-oshun-tier=pro`** — paid templates / locales become available
- [ ] **`x-oshun-tier=premium`** — full template set available
- [ ] **`x-oshun-living-scenes-enabled=false`** — tenant policy disables Living
      Scene; the card renders the disabled state
- [ ] **`x-oshun-living-scene-templates` whitelist** — only templates in the
      approved set + the header subset render
- [ ] **`x-oshun-living-scene-frozen-workflow-classes` set** — listed workflow
      classes are frozen; mutating actions disabled
- [ ] **`x-oshun-living-scene-locales` set** — Living Scene exposes the listed
      locales only
- [ ] **Default locale fallback** — when `x-oshun-locale` is absent the page
      uses `en-US`
- [ ] **Reduced motion** — Living Scene animations honor preference (handled
      inside `LivingSceneCard`)
- [ ] **Offline** — page is server-rendered; subsequent generation requests use
      the SW cache where applicable

## Interactions

All interactive controls live inside the `LivingSceneCard` component
(approved-template picker, generation trigger, preview pane, locale switch).
Walk that component when verifying:

- [ ] **Template picker** (only approved templates allowed)
- [ ] **Locale switch** (constrained to `allowedLocales` when set)
- [ ] **Generate** (gated by tier + frozen workflow class set)
- [ ] **Preview surface** — renders generated output
- [ ] **Disclosure banner** — surfaces tenant-policy state

## Data & contracts

- **Reads (server)**:
  - `headers()` — `x-oshun-tier`, `x-oshun-locale`,
    `x-oshun-living-scenes-enabled`, `x-oshun-living-scene-templates`,
    `x-oshun-living-scene-frozen-workflow-classes`,
    `x-oshun-living-scene-locales`
- **Reads (library)**: `@yemaya/living-scenes-runtime` —
  `APPROVED_LIVING_SCENE_TEMPLATE_IDS`, `LivingSceneCustomerTier`,
  `LivingSceneTenantPolicy`, `LivingSceneTemplateId`
- **Writes**: handled inside the `LivingSceneCard` (generation requests)
- **Caching**: SSR with header-derived inputs; SW caches static assets
- **Auth/role check**: middleware allows anonymous (PUBLIC_PATHS); tier + tenant
  policy enforced inside the page and the runtime library

## Cross-references

- Parent: [`../studio-overview.md`](../studio-overview.md)
- Sibling: [`studio-generation-gallery.md`](./studio-generation-gallery.md),
  [`studio-asset-preview-pipeline.md`](./studio-asset-preview-pipeline.md),
  [`../authoring/studio-compose.md`](../authoring/studio-compose.md)
- Component source:
  `apps/oshun/web/src/components/studio/generation/LivingSceneCard.tsx`

## Open questions / known gaps

- [ ] Confirm whether the public route stays anonymous in production or becomes
      signed-in once Yemaya entitlements are integrated
- [ ] Document the upstream proxy that injects `x-oshun-*` headers (Cloudflare
      worker? BFF middleware?)
