Strip
Responsibility
Section titled “Responsibility”Strip is the Go SSR frontend for internal/admin-style workflows.
Runtime
Section titled “Runtime”Strip uses Go, Fiber, Templ, and Tailwind. The build order is Templ, Tailwind, then the Go binary.
Design System
Section titled “Design System”Strip’s interface uses the Foxy design system: Rethink Sans for UI type and Parisienne for the wordmark and script accents, the Foxy pink/red/ink palette, fully rounded pill controls, and soft cards over a light or dark canvas. Design tokens are defined as Tailwind v4 semantic CSS variables in apps/strip/internal/app/assets/css/input.css, and the always-dark sidebar rail plus the brand wordmark/butterfly assets in apps/strip/internal/app/assets/ drive the shared chrome. When restyling, change tokens and shared components first so every page inherits the update rather than styling page by page.
Primary Source Paths
Section titled “Primary Source Paths”- apps/strip/cmd/
- apps/strip/internal/app/
- apps/strip/cmd/build-assets/
Contracts And Generated References
Section titled “Contracts And Generated References”Strip talks to sirloin over the proto/sirloin/v5/ subset it consumes.
Related Flows
Section titled “Related Flows”Related Standards
Section titled “Related Standards”Related Decisions
Section titled “Related Decisions”Strip decisions live under docs/src/content/docs/decisions/ when durable.
Operations
Section titled “Operations”The templ CLI must be available on the host before local build commands run.
Media tagging preflight
Section titled “Media tagging preflight”With an Admin or Root account, open Popular Examples → Media preflight.
Upload the private selection.json, then select Run preflight. The selection
must contain 30 distinct examples: 10 images, 15 videos and 5 five-image carousels.
The Sirloin preflight documents the input
format and the checks. Strip preserves the uploaded bytes and their selection
hash. Do not upload credentials or media URLs.
Sirloin checks the media in a background River job using its existing database, S3 and Brain connections. Strip polls the job and displays its status and counts. Download full JSON saves every example’s result and failure reason in the complete receipt. Keep this file private. Download it within 24 hours, before completed jobs expire. Reloading the result URL retrieves the saved job rather than starting another run.
The check prepares media and builds a model request without sending it. It does not enroll examples, activate tagging, or change catalogue or Brain records. Only the job and report are stored. A matching active selection reuses its job; a different selection must wait until the active run finishes. Both RPCs check the operator’s current Admin or Root role and use the same closed-VPC trust boundary and optional service-token enforcement as other Strip RPCs.
Sources: apps/strip/internal/app/handlers/mediapreflight.go,
apps/sirloin/internal/app/services/strip/stripmediapreflight.go, and
apps/sirloin/internal/app/worker/mediapreflight.go.
Restore a deleted character
Section titled “Restore a deleted character”In Characters, open Filters and set Deletion to Deleted only. Search by character name, owner email, or character ID. Open the character’s details, select Restore character, and confirm. Support, Admin, and Root roles can restore characters. The list refreshes with its filters preserved.
Restoration clears the character’s deletion timestamp and records the operator
in the audit log. It does not recover deleted dataset images, retrain the
character, or reverse refunds. If another active character uses the Foxy handle
or occupies the same adult identity slot, restoration fails without changing either character.
See apps/strip/internal/app/handlers/characterrestore.go and
apps/sirloin/internal/pkg/storage/striprestorecharacter.go.
Reset an account’s selfie verification
Section titled “Reset an account’s selfie verification”Open user details and find the selfie reset controls beside KYC. The count is account lifetime usage, including support resets. Customers can reset three times; afterward Brisket explains that they must contact support. Enter a reason and confirm using a Support, Admin or Root account with selfie-reset permission. No character or open setup session is required.
This action resets account-wide KYC immediately. Tell the customer to complete verification again. It does not issue a reusable grant, replenish the customer’s allowance, or change character adult approvals, identity anchors, assets or media. The reset history and Strip audit record the reviewer, reason and count change in the same transaction. Retrying a submitted request cannot perform another reset; stale verification requires refreshing user details.
Support overrides only the three-reset quota. Approved current KYC is still
required, and the existing NSFW-media eligibility rule still applies. Deleting
the relevant media or character can remove the media block,
but never restores reset allowance. Adult enablement alone does not block resets.
See account reset semantics and
apps/sirloin/internal/pkg/storage/accountselfiereset.go.
Change a user’s NSFW routing
Section titled “Change a user’s NSFW routing”In a user’s details, Payment processors → NSFW routing sets the NSFW
processor and the merchant account (MID) Primer routes the user by. CS picks one
processor and MID pair from a fixed list in Strip’s code, chosen by
STRIP_STAGE: production lists the live merchant accounts, every other stage the
Primer sandbox ones. A “no MID” route clears the MID, which sends the user to
the workflow’s default branch; on NMI the next subscription settle backfills
the MID it settled on, so a cleared NMI MID lasts only until then. MIDs are case-sensitive Primer literals, so a new
merchant account is added to the list in the same release as its Primer
workflow branch. Strip and Sirloin ship from the same merge; until the Sirloin
that stores the MID is live, Sirloin ignores nsfw_processor_mid and still
reports success, so check Current after saving.
Support, Admin and Root roles can edit it, and every change is in the
audit log with the MID before and after. A MID the user’s saved card cannot be
charged on declines their renewals, so change it only for a user whose payments
are known to belong there. See apps/strip/internal/app/config/nsfwroutes.go
and apps/sirloin/internal/pkg/storage/stripupdateuser.go.
Clerk Impersonation
Section titled “Clerk Impersonation”Strip authenticates operators against its own Clerk instance with STRIP_CLERK_SECRET_KEY.
The user impersonation button mints Clerk actor tokens for main app users, so it must use
STRIP_IMPERSONATION_CLERK_SECRET_KEY from the main app Clerk instance instead. Do not
reuse Strip’s admin Clerk secret for this value.
Local Commands
Section titled “Local Commands”- cd apps/strip && make build
- cd apps/strip && make run-tests
- cd apps/strip && make lint
CI runs the same checks in .github/workflows/strip.yml and reports them as the
strip check. CI pins golangci-lint v2.14.0, so a different local version can
disagree with it. CI also fails when templ generate changes committed files,
because the Railway build regenerates Templ code before go build.