Character Creation
Character Creation
Section titled “Character Creation”Purpose
Section titled “Purpose”Document how Brisket requests character creation and how Sirloin validates KYC, usage, credits, and reference image handling.
Characters V2 Entry Points
Section titled “Characters V2 Entry Points”Characters V2 uses recipe-family creation from both the Characters roster and the Explore template gate. A family that requires a selection opens the shared selector dialog with its catalog title, optional description, options, availability, and quoted prices. The chosen family revision, option, and price are submitted together. Families without a selector start directly. See the roster chooser and Explore creation actions.
Before a new paid start, Brisket fetches fresh usage. A subscribed account whose combined credit balance is below the selected quote sees the existing top-up checkout and no start request is sent. Free starts skip this lookup; unsubscribed accounts retain the existing creation flow. An unconfirmed start replays its original request without another balance check because credits may already be reserved. Results from a lookup are ignored after an account change or unmount. The server remains responsible for validating the quote and reserving credits. Sources: credit preflight, start and reconnect, and the recipe engine.
The V2 Explore gate asks for one photo. Legacy users keep the separate creation
routes, three-photo template copy, and verification checks: the shared layouts
use their original description unless the V2 gate supplies its override.
Eligibility still includes the existing verified staff-email override as well as
the characters-v2 flag. See the
gate routing
and eligibility hook.
In V2 likeness results, an empty photo slot shows an image placeholder. Uploaded photos, required-photo checks, and recovery actions retain their existing behavior. See the photo list.
The direct CreateCharacter sequence below documents the legacy path.
Participants
Section titled “Participants”- Brisket initiates createCharacter through tRPC.
- Sirloin owns character creation, credit consumption, and account-level NSFW/KYC checks.
- Brain provides onboarding image scoring and optional reference nudification.
- S3 stores reference images and account KYC artifacts.
Sequence
Section titled “Sequence”sequenceDiagram
participant Brisket
participant Sirloin
participant Brain
participant Usage
participant S3
Brisket->>Sirloin: CreateCharacter
Sirloin->>Sirloin: Check NSFW KYC prerequisites
Sirloin->>Usage: GetCurrentUsage
Sirloin->>Sirloin: Charge only if existing character count > 0
Sirloin->>S3: Copy KYC/reference images when needed
opt User opts into NSFW without real nude images
Sirloin->>Brain: POST reference-nudify (3 SFW images, bust_size, genitalia_style)
Brain-->>Sirloin: nudified_path for each image
end
Sirloin-->>Brisket: character_id
Source Links
Section titled “Source Links”- apps/brisket/src/server/api/routers/character.ts
- apps/sirloin/internal/app/services/characters/createcharacter.go
Reference Image Moderation
Section titled “Reference Image Moderation”Character reference image scoring uses the Brain onboarding checkpoint. Sirloin maps Brain validation and moderation failures into character dataset image failure reasons for Brisket. See Image Moderation And Age Scoring for the moderation checkpoints and demographics age-scoring rules.
Reference Image Nudification
Section titled “Reference Image Nudification”Nudification is an optional step during character creation that enables NSFW capabilities for users who do not want to upload their real nude images. Instead of requiring actual NSFW photos, the system takes the user’s SFW onboarding images (FACE_FRONTAL, FULL_BODY, FULL_BODY_ANY) and generates synthetic NSFW reference variants using AI.
After onboarding images are scored, Sirloin can request Brain to generate nudified variants via POST /api/onboarding/reference-nudify. Brain’s NudifyService selects random body-part reference images from the Body Parts Library, reads LoRA configuration from application settings, and launches 3 concurrent WaveSpeed inference jobs. The resulting nudified images are stored in R2 and their paths returned to Sirloin for use as NSFW reference material.
This path matches reference images strictly on a single attribute and does not use the wildcard rule that the workflow node applies; see Body Parts Library for the catalogue, its taxonomy and the difference between the two consumers.
See Brain API — Reference Nudify for endpoint details.
State Transitions
Section titled “State Transitions”The first character has no credit charge because cost is only charged when usage.GetCharactersCount() > 0. Additional characters cost 10 credits from characterCreditsCost and use ConsumeCreditsWithBreakdown. New records start pending unless the request path marks them available.
Invariants
Section titled “Invariants”- NSFW character creation requires approved account KYC.
- Additional characters cost 10 credits.
- GFY model type is rejected.
- Reference character images may be copied through S3.
- A customer read never returns an asset that is not
available. The filter lives in one SQL query builder,characterBindingAssetProjectioninapps/sirloin/internal/pkg/storage/characterprojection.go, which every projection asset response goes through — session, roster, and management. Each caller supplies only the base relation: the live binding pointer (throughcharacterProjectionAssetQuery) or one session’s working set. It is not repeated per read path: the session path used to filter in its service layer while the projection paths did not filter at all, so a rejected upload came back from the roster with a working signed URL. Other paths querycharacter_asset_bindingsdirectly by design and do not use that builder: action and selection validation, execution input snapshots, enhancement, capability resolution, identity snapshots and restore, the discard tombstone, and the lineage walk. None of them returns an object key to a customer; the ones that care about state test it themselves.
Error Paths
Section titled “Error Paths”Sirloin returns FailedPrecondition when NSFW KYC prerequisites are missing, ResourceExhausted for insufficient credits or character limits, and InvalidArgument for deprecated model types.
These are the error paths of the direct creation call documented above. Recipe-driven creation (Characters V2) adds a second, customer-visible outcome that is not an error: a compute step may decline the input a customer supplied, such as a photograph it will not accept. That decline is a successful execution carrying a verdict in the workflow’s declared output. For a photo decline, the session remains on the photo-validation stage with only the authored retry transition available; choosing another photo follows that transition back to upload instead of surfacing a gRPC status. See Character workflow verdicts are outputs and the Character Recipe Engine.
Tests And Verification
Section titled “Tests And Verification”- cd apps/sirloin && make run-tests
- Target create-character tests when changing KYC or credit behavior.