# Creator Suite — Lilith Studio

Lilith Studio is the creator suite of the Lilith Metaverse — the place a creator
builds the things a room is made of before anyone walks into it: the room itself
(scene and prop authoring), the body people wear inside it (avatars and
costumes), and the workflow that turns both into a published, provenance-stamped
artifact a client can render. Where the
[Tara authoring page](./tara-authoring-personas-tone-economics.md) covers what a
yoga instructor _teaches_, this page covers what every creator _makes_, and it
carries a different burden of proof. The question here is not "is the class
trauma-informed?" but **"who edits what, where — and is the thing they shipped
provably the thing the client renders, with its provenance attached?"** Lilith
Studio answers that with a hard authoring split (a yoga teacher publishes from a
web form; an environment artist builds the venue in UE5), a real avatar pipeline
that re-costumes a body without reloading its mesh, and a content pipeline that
reconciles git and Perforce. The strongest code lives in
`libs/v3/avatar-pipeline` (the `@oshun/avatar-pipeline` package); the scene side
is honest about where its art actually lives. The deep engine/pipeline treatment
is the architecture companion,
[../architecture/authoring-and-content-pipeline.md](../architecture/authoring-and-content-pipeline.md);
the Commons venues these rooms become, and the live-service calendar that
schedules them, are its sibling
[Commons, venues & live-service](./commons-venues-and-live-service.md). For the
full feature scope this slots into, start at the hub:
[../V3_features.md](../V3_features.md).

## What ships, honestly

The monolith describes a richer creator suite than the tree implements, and the
split is uneven across the two halves of this page — so it is worth stating up
front, because this page follows the code.

- **Avatars and costumes are real and test-covered.** `@oshun/avatar-pipeline`
  is substantive, domain-specific TypeScript — a 7-capability ledger
  (`v3AvatarPipelineDescriptor`, `index.ts:777`), 6 spec suites (~23 `it`
  cases), VRM-1.0 import with identity round-trip, an Oshun-60 retarget rig,
  canonical viseme/emotion/gaze/brow blendshape mapping, material-slot costume
  binding, an 84-variant GA wardrobe, a 32-avatar base gallery, a Ready Player
  Me bridge, a generative-costume gate, and a premium MetaHuman/VRM
  dual-authoring parity check. These are genuine, deterministic, and covered.
- **Scenes are a descriptor and a web shell, not a generator.** The
  environment-art workflow — venue levels, Niagara, Sequencer cue tracks — is
  the UE Editor surface, and those assets live in **Perforce, not git** (the
  arch companion's honest seam). `libs/v3/isis-world-asset` _looks_ like a
  world-asset pipeline but is a typed **capability descriptor** — three keys
  (`asset-brief`, `lod-budget`, `provenance`) and a readiness ratio
  (`index.ts:17`), not a generation runtime. The scene-graph editor, timeline,
  interaction binder, and accessibility checker described in the monolith are
  product spec plus a Next.js shell; do not read `isis-world-asset` as proof
  that V3 procedurally builds venues.
- **The bridge between web and UE is real.** Design tokens are the one place an
  asset is generated from data on the UE side, and that loop is committed:
  `V3Editor`'s `UV3GenerateDesignTokenAssetsCommandlet` + a drift-checking
  `UV3VerifyDesignTokensCommandlet` (`V3GenerateDesignTokenAssetsCommandlet.h`),
  plus the in-editor `UV3DesignTokenReloaderWidget`.
- **MetaHuman art is a contract, not a checked-in mesh.** The premium
  dual-authoring code mints the _deliverable spec_ (a MetaHuman master `.uasset`
  URI + a VRM proxy that share one provenance bundle and one costume-slot
  identifier table). The `.uasset` itself is UE/Perforce-resident; the parity
  contract is code.

## Scene and room authoring

### Where the environment actually lives

Scene and room authoring is the environment-art workflow, and it runs in the
**UE Editor**: a creator composes a venue level, places props and lighting and
audio sources, builds Niagara systems for ritual and concert VFX, and lays
Sequencer cue tracks for cinematic moments. None of that art is in this
repository, and that is deliberate — per the arch companion's "Content Pipeline
and Source Control" seam, UE binary assets (`*.uasset`, `*.umap`) are versioned
in **Perforce**, while the code modules and Game Feature plugins live in git.
The `.gitignore` encodes exactly this division, whitelisting only the two
machine-generated asset classes (the 21 `GameFeatureData.uasset` registration
assets and the design-token assets) against a global `*.uasset` ignore.

This is also where the most tempting misread lives. `libs/v3/isis-world-asset`
has a generation-shaped name, but its `index.ts` exports a three-capability
descriptor (`asset-brief`, `lod-budget`, `provenance`) with operational-metric
strings and a `v3IsisWorldAssetReadinessScore` that ratios matched capabilities
(`index.ts:45`) — it is the readiness _contract_ for Isis world-asset
generation, not the runtime that builds a venue. The procedural scene-graph
editor, the cinematic timeline, the `button → action` interaction binder, the
capacity-tier/sharding setter, and the pre-publish accessibility checker
(color-vision palettes, motion caps, caption anchoring) the monolith promises
are the product surface; treat them as spec, not as code you can point at here.

### The room as data, and the one asset bridge

What _is_ code on the room side is the metadata-and-tokens layer. The web Studio
carries real Next.js routes under `apps/oshun/web/src/app/lilith-studio/` — a
`scenes/` route (`TaraSceneEditor`) and a `scene/new/` route
(`StudioNewSceneForm`) — through which a creator authors the room-configuration
data that an artist's venue level reads at runtime. And the one place an asset
is generated from data on the UE side is **design tokens**, the bridge both
surfaces must agree on. `V3Editor`'s `UV3GenerateDesignTokenAssetsCommandlet`
parses the web-emitted token manifest and materializes real Slate assets
(brushes, font faces, widget styles), while its twin
`UV3VerifyDesignTokensCommandlet` runs the same pass in read-only mode so any
asset that has **drifted** from the manifest fails verification instead of being
silently rewritten (`V3GenerateDesignTokenAssetsCommandlet.h`). The in-editor
`UV3DesignTokenReloaderWidget` — a real `UEditorUtilityWidget` exposing
`ReloadGeneratedTokens()` with `LastReloadHash` / `LastAppliedWidgetCount`
readback (`V3DesignTokenReloaderWidget.h`) — lets an artist re-apply token
changes live without restarting the editor. A button that looks wrong in one
room looks wrong in every room at once, so this is the bridge that keeps a
creator's palette honest across the web/UE boundary.

## Avatar and costume authoring

This is where the code is strongest, because embodiment has a sharp, testable
burden of proof: an imported body must keep its identity, animate on a canonical
rig, lip-sync to a phoneme set, and re-costume **without reloading its mesh**.
All of it lives in `@oshun/avatar-pipeline`.

### From VRM to the Oshun-60 rig

Authoring a custom avatar starts with a VRM-1.0 upload, and `importVrm1Document`
(`index.ts:843`) parses the glTF document into a typed `ImportedVrm1Avatar` —
meshes, skeleton, blendshapes, materials — with a stable `identityHash` over the
content. `verifyVrm1IdentityRoundTrip` (`index.ts:899`) then proves the import
is lossless: it re-hashes a serialized clone and asserts identical hash, avatar
id, and mesh/bone/blendshape/material counts, so an avatar that mutated in
transit fails loud rather than shipping a silently-degraded body.

Every body retargets onto one canonical skeleton. `OSHUN_60_BONE_NAMES`
(`index.ts:163`) is the literal 60-bone rig — `root` through full finger chains,
plus four IK bones (`leftKneeIk`, `rightKneeIk`, `leftElbowIk`, `rightElbowIk`)
— and `createOshun60RetargetTable` (`index.ts:920`) maps a VRM humanoid onto it,
computing per-bone rotation offsets, an IK translation scale of `1.08`, a
`missingRequiredBones` list, and a `coverage` ratio. `createOshunBlendshapeMap`
(`index.ts:1089`) binds the face: 15 visemes, 8 emotion shapes, 3 gaze, and 2
brow semantics, each resolved through an alias table, and
`evaluateVisemePhraseLipSync` (`index.ts:1166`) renders a 21-cue reference
phrase and asserts frame-exact viseme accuracy. The rig is the contract that
lets one pose or one viseme stream drive any avatar, gallery or imported alike.

### Costume is material slots, not mesh swaps

The headline mechanic is that an avatar is re-costumed by overriding **material
slots**, never by swapping its mesh — so the body never reloads.
`AVATAR_COSTUME_SLOT_NAMES` (`index.ts:382`) defines twelve canonical slots
(`head`, `torso`, `legs`, `feet`, `hands`, `back-prop`, `hip-prop`, `hair`, and
four accessories), `createCostumeSlotBinder` (`index.ts:1194`) computes a stable
`meshSignature` over the avatar's mesh topology, and
`swapCostumeVariantsWithoutReload` (`index.ts:1598`) applies a list of variants
and reports back. Its test is precise (`__tests__/index.spec.ts`): swapping five
reference variants leaves `meshSignatureStable === true`,
`reloadRequired === false`, and ends on
`finalVariantId === 'ritual-white-copper'`. That is the literal proof of the
monolith's "re-costume without reloading the mesh" claim.

Costume changes are also gated per realm. `REALM_COSTUME_SLOT_POLICIES`
(`index.ts:400`) declares which slots each realm allows — Tara 7, Commons 10,
Saraswati all 12 — and `lilithSafetyCostumeRuleCheck` (`index.ts:1251`) refuses
any variant that touches a blocked slot for its realm, returning the offending
`blockedSlots` and human-readable `reasons`. `applyCostumeVariant` only commits
the material overrides when that safety check passes, so an out-of-policy
costume silently no-ops its overrides rather than rendering.

```mermaid
flowchart LR
    v["costume variant"] --> safe{"lilithSafetyCostumeRuleCheck<br/>slot ∈ realm policy?"}
    safe -->|blocked slot| rej["overrides dropped (not applied)"]
    safe -->|approved| apply["material overrides applied"]
    apply --> sig{"meshSignature stable?"}
    sig -->|yes| done["reloadRequired = false"]
```

### The GA wardrobe and the 32-avatar gallery

The shipped wardrobe is real and counted. Three publishers build the GA costume
catalog — `publishTaraTraditionCostumePackToGaGallery` (`index.ts:1290`, 28
variants: 20 yoga-practice + 8 ritual-robe), the Saraswati stage pack (24: six
genre cells × four), and the Commons everyday pack (32: eight culture cells ×
four) — 84 variants in total, each carrying an Isis design review and a
realm-policy pass, with the spec asserting the exact counts (28 / 24 / 32) by
distinct `costumeId`. Custom avatars start from the 32-entry base gallery:
`createOshunCanonicalGallery` (`index.ts:1620`) generates 32 avatars spanning
eight body shapes, four age bands, and eight tradition presentations, and
`validateOshunCanonicalGallery` asserts all 32 are authored, Isis-signed, and
design-passed. Creators who prefer an external editor get the Ready Player Me
bridge: `importReadyPlayerMeBatch` (`index.ts:1764`) validates, normalizes (to
1.72 m, z-forward, ≤1 MB textures), and render-plans a batch, with the reference
test confirming 20 of 20 land render-ready.

### Generative costume and premium personas

Text-to-costume is allowed, but fenced. `requestGenerativeCostume`
(`index.ts:1476`) rejects any request whose creator is not `verified` (the spec
confirms an `unverified` request is rejected), then runs the same
`lilithSafetyCostumeRuleCheck`, attaches an Isis provenance bundle (model card,
prompt hash, signatures), and stamps an editorial-review gate
(`isis-editorial:generative-costume:v1`) before the artifact can be listed —
exactly the monolith's "verified creators only, Isis provenance, operator
review" posture, as fail-loud code rather than prose.

Premium personas are dual-authored, and the parity is the contract. A Saraswati
artist or Tara instructor ships as **both** a high-fidelity MetaHuman master
(Tier-1 Pixel Streaming) and a VRM proxy (Tier-2 web), and
`createPremiumPersonaDualAuthoringDeliverable` (`premium/dual-authoring.ts:106`)
binds them to one shared provenance bundle and one **costume-slot identifier
table** that maps every canonical slot to both a MetaHuman slot path and a VRM
material identifier — so the same costume identifier re-skins both renderings.
`validatePremiumPersonaDualAuthoringDeliverable` asserts the master is a
`.uasset`, the proxy a `.vrm`, the provenance bundle is shared, all 12 costume
slots are present without duplication, and all 28 blendshape semantics match
across both variants. The MetaHuman `.uasset` itself is Perforce/UE art; this
code is the parity _spec_ it must satisfy. The Tara opt-in onto that pipeline
fails loud too — `onboardTaraInstructorPilot`
(`premium/tara-instructor-opt-in.ts:69`) rejects an unverified instructor — and
a likeness-drift gate (`PREMIUM_PERSONA_LIKENESS_DRIFT_THRESHOLD = 0.055`,
`premium/likeness-drift.ts:46`) blocks a premium persona whose rendered angles
drift more than 5.5% from its canonical likeness gallery.

## The creator workflow

### The split, the bridge, the integrity spine

The workflow is organized around one rule, documented exhaustively in the
monolith's "Lilith Studio Authoring Split" table and the arch companion:
anything that is **data** (sequences, room metadata, costume config, consent,
taxonomy) is authored on the **web**; anything that is **art or cinematics**
(venue levels, Niagara, camera cue tracks, MetaHumans) is authored in **UE
Editor**. The web surface is a real Next.js section under
`apps/oshun/web/src/app/lilith-studio/` with committed routes for `scenes/`,
`avatar-costume/` (`AvatarCostumeAuthoring`), `personas/`, and `provenance/`,
among others — a creator who is not an environment artist never needs UE
installed. The UE side is the `V3Editor` module, whose design-token toolchain is
the single bridge where the two surfaces must agree, kept honest by the
drift-checking verify commandlet above.

Persistence is the integrity spine. Published artifacts persist through the
Prisma layer described in the arch companion, where each row carries a
`payloadHash` over its bytes — so the JSON the UE5 client (or the Tier-2
fallback) pulls is provably the same artifact the web authored, not a drifted
copy. That hash column is what lets "who edits what where" stay unambiguous as a
sequence, a room config, or a costume manifest crosses from a web form to a live
room.

### Publish and provenance

Publication flows through V1's environment-promotion gates (preview → editorial
→ release), and every asset a creator touches carries an Isis provenance bundle
— model card, training-data tags, license terms, consent id, watermark hash. The
web Studio's `provenance/` route surfaces that bundle in a creator-facing
inspector so a license conflict is caught _before_ publication rather than via a
post-publication takedown; the same provenance is what the takedown cascade
later keys on. Across the avatar pipeline this is uniform: imported VRMs,
gallery avatars, generated costumes, and premium personas all attach an
`AvatarProvenanceBundle` with Isis `ed25519` signatures, and an inspector
reports any avatar missing a complete bundle. Provenance is not a post-hoc audit
here; it is authored in alongside the asset, which is the foundation the
[identity, safety & provenance page](./identity-safety-provenance-foundations.md)
builds the trust system on.

## Edge cases and failure modes

- **`isis-world-asset` is a descriptor, not a generator.** It publishes three
  capabilities and a readiness ratio; it does not build venues. Cite the UE
  Editor + Perforce art surface for scenes, not this package.
- **An out-of-policy costume silently drops its overrides.** A variant touching
  a slot outside its realm policy fails `lilithSafetyCostumeRuleCheck` and
  applies no material overrides rather than rendering.
- **Re-costuming never reloads the mesh.** The swap test pins
  `meshSignatureStable` true and `reloadRequired` false; a mesh-swap regression
  would fail it.
- **An unverified creator cannot generate a costume.**
  `requestGenerativeCostume` rejects non-`verified` creators before any artifact
  is minted; verified output still passes safety + editorial review.
- **A VRM that mutates on import fails loud.** The identity round-trip asserts
  an unchanged hash and counts, so a lossy import is caught, not shipped.
- **Premium parity is all-or-nothing.** A missing costume slot, a blendshape
  mismatch, or an unshared provenance bundle flips `parityConfirmed` to false.
- **MetaHuman and venue art are Perforce, not git.** The repo holds the
  contracts and the two machine-generated asset classes; the hand-authored art
  is a documented posture with no committed binary here.

## Where this connects

- [Tara: sequence authoring, personas, tone & economics](./tara-authoring-personas-tone-economics.md)
  — the `@oshun/tenant-tara-studio` policy/data tier (21-capability ledger,
  canonical asana library, voice economics) that the web Studio's Tara routes
  author.
- [Commons, venues & live-service](./commons-venues-and-live-service.md) — the
  venues these authored rooms become and the programming calendar that schedules
  them.
- [Identity, safety & provenance foundations](./identity-safety-provenance-foundations.md)
  — the Isis provenance bundles, signatures, and takedown cascade this suite
  authors content into.
- [../architecture/authoring-and-content-pipeline.md](../architecture/authoring-and-content-pipeline.md)
  — the Game Feature Plugin packaging, the web-vs-UE split table, the
  design-token bridge commandlets, and the Prisma `payloadHash` integrity spine
  in depth.
- The feature hub: [../V3_features.md](../V3_features.md).
