Character Creation
Character Creation
Purpose
Document how Brisket requests character creation and how Sirloin validates KYC, usage, credits, and reference image handling.
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
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_idSource Links
- apps/brisket/src/server/api/routers/character.ts
- apps/sirloin/internal/app/services/characters/createcharacter.go
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
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.
See Brain API — Reference Nudify for endpoint details.
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
- 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,characterProjectionAssetQueryinapps/sirloin/internal/pkg/storage/characterprojection.go, which every projection asset response goes through — session, roster, and management. 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
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
- cd apps/sirloin && make run-tests
- Target create-character tests when changing KYC or credit behavior.