Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Promote a feature-flagged feature to Dogfood, Preview, or Stable in the Warp codebase. Use when a feature behind a FeatureFlag is ready to roll out to a broader audience, including wiring up the compile-time/runtime bridge and deferring flag cleanup safely.
.claude/skills/warpdotdev-promote-feature/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | -34% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 22% | 0% |
| case-07 | ✗→✓ | ▲ Improved | -21% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -3% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -19% | 0% |
Guides the staged promotion of a gated FeatureFlag variant to Dogfood, Preview, or Stable, and schedules the follow-up cleanup.
Feature flags have two interacting layers:
warp_core/src/features.rs): DOGFOOD_FLAGS, PREVIEW_FLAGS, RELEASE_FLAGS — enabled per-channel at startup.app/Cargo.toml + app/src/lib.rs): Cargo features in [features]. The default = [...] array enables a feature for all builds. enabled_features() in app/src/lib.rs bridges each Cargo feature to its FeatureFlag variant via #[cfg(feature = "...")].Do not remove the flag immediately after promoting to Stable. Keep it for at least 1–2 release cycles so a rollback is a one-line PR (remove the entry from default). Use the remove-feature-flag skill for the cleanup step later.
The per-channel arrays in warp_core/src/features.rs (DOGFOOD_FLAGS/PREVIEW_FLAGS/RELEASE_FLAGS) are shared and drive both the GUI desktop app (app/) and the headless TUI (crates/warp_tui) at runtime. The app/Cargo.toml default + app/src/lib.rs enabled_features() compile-time bridge is GUI-app-only. If a promoted feature should also reach the TUI, make sure it is enabled at runtime for the target channel (the shared arrays already do this) and, if the feature relies on a compile-time Cargo feature, that the TUI binary (crates/warp_tui/Cargo.toml) enables it too.
Add the flag to DOGFOOD_FLAGS in warp_core/src/features.rs:
rustpub const DOGFOOD_FLAGS: &[FeatureFlag] = &[ // ... FeatureFlag::YourFeature, ];
No other file changes needed.
PREVIEW_FLAGS in warp_core/src/features.rs.DOGFOOD_FLAGS if present — Preview flags are automatically included in Dogfood builds.rustpub const PREVIEW_FLAGS: &[FeatureFlag] = &[ // ... FeatureFlag::YourFeature, ];
This requires changes in three files.
app/Cargo.toml — add to defaultAdd the snake_case feature name to the default = [...] array:
tomldefault = [ # ... "your_feature_name", ]
Prefer this over adding to RELEASE_FLAGS (see comment at warp_core/src/features.rs:787-790). It compiles the feature into all builds and enables a one-line rollback.
app/src/lib.rs — add to enabled_features() bridgeAdd a #[cfg(...)] entry inside the flags.extend([...]) block in enabled_features(), following the existing pattern:
rust#[cfg(feature = "your_feature_name")] FeatureFlag::YourFeature,
Place it near logically related entries.
warp_core/src/features.rs — remove from PREVIEW_FLAGS / DOGFOOD_FLAGSRemove the variant from whichever arrays it currently lives in:
rustpub const PREVIEW_FLAGS: &[FeatureFlag] = &[ // Remove FeatureFlag::YourFeature, ];
bashcargo clippy -p warp_core --all-targets --tests -- -D warnings # Also lint the GUI app when app/Cargo.toml or app/src/lib.rs changed. cargo clippy -p warp --all-targets --tests -- -D warnings # Also lint the TUI when crates/warp_tui/Cargo.toml changed. cargo clippy -p warp_tui --all-targets --tests -- -D warnings ./script/format
If the promotion changes behavior beyond flag lists or configuration, run affected tests before Clippy. Format once after all other changes are complete. Do not rerun earlier checks after formatting or add a full presubmit unless explicitly required; CI owns broader platform and workspace coverage.
After the PR lands, create a Linear issue to remind the team to remove the flag. Use the Linear MCP tool:
save_issue(
title: "Remove FeatureFlag::YourFeature after stabilization",
team: <your team>,
assignee: "me",
description: "FeatureFlag::YourFeature was promoted to Stable in <PR link>. Remove the flag and dead code branches after 1–2 release cycles. Follow the `remove-feature-flag` skill.",
labels: ["tech-debt"],
priority: 4 // Low
)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 16,109 | 18,268 | +13% | 1 | 1 | 0% | 235 | 1,384 | +489% | 0 | 0 | — |
case-02 | fail→fail | 20,882 | 12,666 | -39% | 1 | 1 | 0% | 1,956 | 1,399 | -28% | 0 | 0 | — |
case-03 | fail→fail | 7,470 | 7,455 | -0% | 1 | 1 | 0% | 194 | 1,545 | +696% | 0 | 0 | — |
case-04 | fail→pass | 13,184 | 3,881 | -71% | 1 | 1 | 0% | 2,477 | 1,624 | -34% | 0 | 0 | — |
case-05 | pass→pass | 9,649 | 3,443 | -64% | 1 | 1 | 0% | 1,407 | 1,624 | +15% | 0 | 0 | — |
case-06 | fail→pass | 10,716 | 5,919 | -45% | 1 | 1 | 0% | 1,762 | 2,149 | +22% | 0 | 0 | — |
case-07 | fail→pass | 59,179 | 9,101 | -85% | 1 | 1 | 0% | 2,454 | 1,944 | -21% | 0 | 0 | — |
case-08 | fail→fail | 13,249 | 4,033 | -70% | 1 | 1 | 0% | 1,803 | 1,627 | -10% | 0 | 0 | — |
case-09 | fail→pass | 26,412 | 5,300 | -80% | 1 | 1 | 0% | 1,933 | 1,870 | -3% | 0 | 0 | — |
case-10 | fail→pass | 21,657 | 3,894 | -82% | 1 | 1 | 0% | 1,953 | 1,582 | -19% | 0 | 0 | — |
case-11 | fail→pass | 12,855 | 4,459 | -65% | 1 | 1 | 0% | 2,191 | 1,891 | -14% | 0 | 0 | — |
case-12 | fail→pass | 7,113 | 2,913 | -59% | 1 | 1 | 0% | 833 | 1,573 | +89% | 0 | 0 | — |
case-13 | fail→pass | 13,125 | 3,401 | -74% | 1 | 1 | 0% | 1,319 | 1,632 | +24% | 0 | 0 | — |
case-14 | pass→pass | 7,391 | 2,975 | -60% | 1 | 1 | 0% | 1,094 | 1,464 | +34% | 0 | 0 | — |
case-15 | fail→pass | 10,821 | 4,670 | -57% | 1 | 1 | 0% | 1,597 | 1,691 | +6% | 0 | 0 | — |
case-16 | fail→pass | 11,252 | 3,386 | -70% | 1 | 1 | 0% | 1,432 | 1,630 | +14% | 0 | 0 | — |
case-17 | fail→fail | 10,699 | 13,411 | +25% | 1 | 1 | 0% | 1,639 | 2,200 | +34% | 0 | 0 | — |
case-18 | fail→pass | 9,760 | 4,350 | -55% | 1 | 1 | 0% | 1,308 | 1,650 | +26% | 0 | 0 | — |
case-19 | pass→fail | 15,410 | 8,675 | -44% | 1 | 1 | 0% | 2,525 | 1,556 | -38% | 0 | 0 | — |
case-20 | pass→pass | 12,618 | 16,364 | +30% | 1 | 1 | 0% | 2,391 | 3,315 | +39% | 0 | 0 | — |
case-21 | pass→pass | 11,091 | 7,954 | -28% | 1 | 1 | 0% | 2,047 | 2,305 | +13% | 0 | 0 | — |
case-22 | fail→pass | 11,633 | 3,703 | -68% | 1 | 1 | 0% | 1,634 | 1,728 | +6% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 18 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.