Skip to content

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_id
  • 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, characterProjectionAssetQuery in apps/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 query character_asset_bindings directly 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.