---
path: /lilith-studio/avatar-costume
surface: customer
domain: lilith
auth: signed-in + role:v1_editorial_producer (default)
source: apps/oshun/web/src/app/lilith-studio/avatar-costume/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'
---

# Lilith Studio · Costume slot authoring

## Purpose

Configure a body-safe avatar costume slot — pick a garment + palette + safety
variant for a costume slot, generate a preview artifact, round-trip through V1
editorial approval, and release a versioned costume edition with provenance
attached. The page
(`apps/oshun/web/src/app/lilith-studio/avatar-costume/page.tsx`) returns
`<AvatarCostumeAuthoring />` 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`) — "Avatar and costume" surface tab
  → "Open Avatar and costume" link
- **Direct URL / bookmark** — yes (signed-in)

## Layout regions

`AvatarCostumeAuthoring`
(`apps/oshun/web/src/app/lilith-studio/avatar-costume/AvatarCostumeAuthoring.tsx`):

- **Header**: eyebrow "Lilith Studio / Avatar costume", title "Costume slot
  authoring", lede, two header actions — "Lilith shell" → `/lilith-studio`, "V1
  asset library" → `/studio/yemaya/asset-library`
- **Three-panel grid**:
  - **Slot configuration panel** (`aria-label="Costume slot configuration"`):
    - Costume slot `<select>` (`data-lilith-costume-slot-select`) — four
      options: Torso wrap, Lower drape, Headpiece, Hand prop
    - Garment `<select>` (`data-lilith-costume-garment-select`) — four options
      gated by slot: Tara practice shawl, Lotus walking sash, Moon crown,
      Practice mala
    - Palette `<select>` (`data-lilith-costume-palette-select`) — three options:
      Moss and gold, Lotus and silver, Night rose
    - Safety variant `<select>` (`data-lilith-costume-safety-select`) — three
      options: Body-safe fit, No face occlusion, Low-motion cloth
  - **Preview panel** (`aria-label="Avatar costume preview"`):
    - Avatar silhouette canvas (`data-lilith-costume-preview-canvas`) with
      head/body/slot sprites posed by `slotId`
    - Preview meta strip — garment label, palette label, safety label
    - Preview evidence: kicker "Preview artifact",
      `preview:<slot>: <garment>:<palette>` strong, provenance ID
  - **Round trip controls panel** (`aria-label="Round trip controls"`):
    - Stage list (`data-lilith-costume-round-trip-list`): three `StageItem`s —
      Preview, Editorial, Release (active / done indicators)
    - Actions: "Generate preview" (`data-lilith-costume-generate-preview`,
      primary, only when `roundTrip.canPreview`), "Send for editorial review"
      (`data-lilith-costume-submit-editorial`), "Approve editorial"
      (`data-lilith-costume-approve-editorial`), "Release costume slot"
      (`data-lilith-costume-release`, release button)
- **Release evidence section** (`aria-label="Release evidence"`):
  - Evidence grid: Palette (`label · swatch`), Policy tag (the safety variant's
    `policyTag`), Release status
  - Release manifest textarea (read-only,
    `data-lilith-costume-release-manifest`)
- **`LilithProvenanceInspector`** — surface ID `avatar-costume-authoring`, asset
  list combines garments + palettes + safety variants

## States

- [ ] **Loading** — client component; `data-hydrated="false"` until mount
- [ ] **Default draft** — slot `torso-wrap`, garment `tara-shawl`, palette
      `moss-gold`, safety `body-safe`, stage `draft`
- [ ] **Stage progression** —
      `draft → preview → editorial → approved →     released` (each button
      unlocks only at the prior stage)
- [ ] **Slot changed** — `changeSlot` resets garment to the first matching slot
      and returns to draft
- [ ] **Garment / palette / safety changed** — resets to draft
- [ ] **Released** — `data-release-edition-id="release:<slot>:<garment>"`
- [ ] **Offline** — client-only; no network; works offline

## Interactions

### Header

- [ ] **"Lilith shell" link** — href `/lilith-studio`
- [ ] **"V1 asset library" link** — href `/studio/yemaya/asset-library`

### Slot configuration selects

- [ ] **Costume slot select** — sets `slotId`; calls `changeSlot` which also
      resets garment
- [ ] **Garment select** — disabled options for non-matching slots; sets
      garment; resets draft
- [ ] **Palette select** — sets palette; resets draft
- [ ] **Safety variant select** — sets safety; resets draft

### Round-trip buttons

- [ ] **"Generate preview" button** (primary)
  - Function: `setStage('preview')`
  - Disabled when `stage !== 'draft'`
- [ ] **"Send for editorial review" button**
  - Function: `setStage('editorial')`
  - Disabled when `stage !== 'preview'`
- [ ] **"Approve editorial" button**
  - Function: `setStage('approved')`
  - Disabled when `stage !== 'editorial'`
- [ ] **"Release costume slot" button** (release button)
  - Function: `setStage('released')`
  - Disabled when `stage !== 'approved'`

### Release evidence

- [ ] **Release manifest textarea** (read-only,
      `aria-label="Avatar costume release manifest"`)

### Provenance inspector

- [ ] **`LilithProvenanceInspector`** — read its own walkthrough

## Data & contracts

- **Reads**: in-file constants `AVATAR_COSTUME_SLOTS`,
  `AVATAR_COSTUME_GARMENTS`, `AVATAR_COSTUME_PALETTES`,
  `AVATAR_COSTUME_SAFETY_VARIANTS`, `AVATAR_COSTUME_PROVENANCE_ASSETS`
- **Writes**: client state only (no network in code)
- **Realtime**: none
- **Caching**: client bundle
- **Auth/role check**: middleware enforces signed-in

## Cross-references

- Studio shell: [`lilith-studio.md`](./lilith-studio.md)
- Sibling editors: [`lilith-studio-asana.md`](./lilith-studio-asana.md),
  [`lilith-studio-personas.md`](./lilith-studio-personas.md),
  [`lilith-studio-scenes.md`](./lilith-studio-scenes.md),
  [`lilith-studio-music.md`](./lilith-studio-music.md),
  [`lilith-studio-concerts.md`](./lilith-studio-concerts.md),
  [`lilith-studio-provenance.md`](./lilith-studio-provenance.md)
- Component source:
  `apps/oshun/web/src/app/lilith-studio/avatar-costume/AvatarCostumeAuthoring.tsx`

## Open questions / known gaps

- [ ] Confirm whether release IDs persist to V1 release edition or stay in
      client state
- [ ] Verify the body-persona safety policy contract — the `policyTag` strings
      (`persona.body.safe-fit` etc.) reference Lilith policy; cross- check with
      `V1/features.md#lilith-persona-policy`
- [ ] Confirm whether the avatar silhouette previews actual garment art or is
      only a stub silhouette
