import dynamicConfig1 from './dynamic_config_1.png';
import dynamicConfig2 from './dynamic_config_2.png';

# Model Launches - Dev + TPM

Relevant doc: [Model Visibility / Accessibility Control](https://www.notion.so/Model-Visibility-Accessibility-Control-1ecb01573ccf80768146d7c275a2205a?pvs=21) 

## Getting ready to launch a model runbook (updated Oct 2025)

When ML decides a model is done cooking, here are the steps to get it out into the world:

- Add to `bots_modeltype` DB table with appropriate name, display priority, description, external key, capabilities, and features.
    - Ensure that features and capabilities are first added to `ModelFeature` text choices [here](https://github.com/suno-ai/glockenspiel/blob/main/studio_api/studio_api/bots/models.py#L1515) to prevent schema errors coming out of studio API.
    - Staging - the model will immediately become available in staging.
    - Prod - nothing will happen till we add some rules to the `model-access` dynamic config. See below “Launching a model runbook.”
- Make sure we handle the model’s display name by adding some boilerplate in `_get_major_model_version()` [here](https://github.com/suno-ai/glockenspiel/blob/main/studio_api/studio_api/bots/models.py#L573) to map a model’s external key to its display name in the UI.
    - Until we do this, no badges will show up next to songs generated with the new model since their display name will be empty
- Defaulting to the new model (tl;dr this should come for free as long as backend returns `is_default_model` appropriately):
    - Make sure that the backend returns the correct default model in `/billing/info` response `models`. The field you’re looking for is `is_default_model`.
    - This should work out-of-the-gate since the billing API returns the highest possible model as the default (per display priority).
    - Once default model changes, the front-end will default once to that model if it hasn’t been seen before.
    - For free users, we can also update the default free model (currently only options are 3.5 or 4.5-all) in [this dynamic config](https://console.statsig.com/64RBMXCoSmsTc9oTU9ghAk/dynamic_configs/default-free-model)
- Model badge color
    - If launching a new “latest” model that should be branded with pink, update `LATEST_MODEL_VERSION` [here](https://github.com/suno-ai/glockenspiel/blob/main/studio_api/studio_api/bots/constants.py#L1938). Old model version badges will be gray and the latest will be pink.
- In-app promo
    - Banners are driven by [this dynamic config](https://console.statsig.com/64RBMXCoSmsTc9oTU9ghAk/dynamic_configs/banner-section-config)
    - Modals are driven by (CMS SET UP BY REET)
- Remaster
    - Remaster models are configured in [this dynamic config](https://console.statsig.com/64RBMXCoSmsTc9oTU9ghAk/dynamic_configs/remaster-models). To add a new remaster model, simply update the config and it will show up in the dropdown. Mobile will use the latest (top) remaster model.
- Model description localization
    - Follow the steps outlined in [glockenspiel localization](https://www.notion.so/glockenspiel-localization-23ab01573ccf80a2aba0c65d017b19dd?pvs=21) to add translations to our backend project.
- Feature/capability access
    - In the web frontend, use `isFeatureEnabledForPlan()` or `doesModelSupportFeature()` - DO NOT HARDCODE MODEL NAMES.
    - We should keep `accessible_features` correct in `/billing/info` as a source of truth - DO NOT HARDCODE FEATURE NAMES.
- Launch checklists
    - Refer to the v5 launch checklist [here](https://docs.google.com/document/d/15fm36zmI5r-ljC9ex2DLjUc8gR0hXb5gzXb1A6XqRu8/edit?tab=t.q51bs9u1bl22#heading=h.m10hpa5982vc) to see how we’ve set these up in the past. Also includes info on changing subscription descriptions, etc.

## Launching a model runbook (updated Sept 2025)

1. Create a feature gate for rollout of the new model. Set the pass % to 0 in production.
2. Add new rules to the [model-access dynamic config](https://console.statsig.com/64RBMXCoSmsTc9oTU9ghAk/dynamic_configs/model-access) to give users for whom the above feature gate is True access to the model. Generally if it’s a paid model you’ll want to create mobile and web rules directly above the existing paid users rules for mobile and web. If it’s a free model you’ll have to put the rule further down the chain. Make sure you have someone that can review your changes to the dynamic config. Set the pass % to 100 and include the new model in the returned JSON.
    1. For new paid models on mobile, create a rule directly under `PROD - MOBILE - Staff`
    2. For new paid models on web, create a rule directly under `Prod - WEB - Staff`
    3. For new free models, you’ll still want to create a new rule so that we can do a gradual roll-out. After that’s done, though, you can add the new model to the default and remove the rollout rule.
3. On launch day, work with ML to decide at what pace we want to ramp up traffic. Gradually increase the pass % of your feature gate until we reach 100%.
4. After launching, clean up the model-access config and add the new model with `can_use=False` to default rule as well as the other rules for users without access in order to enable upsells.

**Example Usage**

We are launching v4.5+. Previously, paid users had access to v4 and v4.5, so there’s a rule in the model-access dynamic config like this:

<img src={dynamicConfig1.src || dynamicConfig1} alt="Dynamic Config 1" />

First we make a new feature gate `bluejay-rollout` and set the pass % to 0 in prod.

Then we will add a rule directly above the existing paid users rule to launch new paid model v4.5+. It will contain the same rules plus an extra condition that the user passes the rollout feature gate, like this:

<img src={dynamicConfig2.src || dynamicConfig2} alt="Dynamic Config 2" />

The new rule’s returned JSON should include the new model with `can_view=True` and `can_use=True`.

On launch day, we can ramp up the pass % for the feature gate and then, once done, we can clean up model access by adding the new model to the original rule and removing the rule with the extra “Passes Target Gate” condition.

After launch, we can add the new model to all the rules for users without access with `can_view=True` and `can_use=False` in order to enable in-app upsells.

## A note on Early/VIP access

This config will get very messy very quickly if we expand rules. To avoid this, we should create ONE rule for early access. Use a Statsig segment so we can update who gets early access without changing the `model-access` rules. 

After launching a new model, we should remove the early access rule in favor of consolidating to ONE rule that comprises every user who might not be paid but should have access to all models. Theoretically this can be the `skip-paywall` group.