add-feature-flag
Skill1 starsChanged 2 months agoApache-2.0View on GitHub
Add a runtime feature flag (AppConfig-backed on prod, secret fallback off-prod), global by default or optionally gated by org id, user id, or platform admin
We split this skill into the rules it gives an agent
11 rules. 0 are common, 4 are distinctive, and 7 are very specific to this project.
0
Common
Most of the 8 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
If the user wants a fixed per-deployment toggle, send them to env-flags.ts instead.
- Distinctive: line 35
Confirm the granularity before editing code: If the user has not already specified it, stop and ask:
- Distinctive: line 40
If the user chooses scoped gating but does not name the dimensions, ask which of organization, user, and platform admin it needs.
- Very specific: line 41
If the user wants a fixed per-deployment toggle rather than a runtime AppConfig flag, use env-flags.ts instead.
- Very specific: line 43
Define the flag: Add one entry to the FEATURE_FLAGS registry in apps/sim/lib/core/config/feature-flags.ts.
- Distinctive: line 66
Do not fetch, resolve, or thread through user or organization context solely for a global flag.
- Very specific: line 85
Test: Add a case to apps/sim/lib/core/config/feature-flags.test.ts that matches the chosen granularity.
- Very specific: line 87
Clean up after rollout: When the feature ships to everyone, delete the flag's entry from FEATURE_FLAGS, the <FLAG_SECRET> env entry, the …
- Very specific: line 92
Never read flags via raw fetch or a new AppConfig client — always go through isFeatureEnabled / getFeatureFlags.
- Very specific: line 93
Never bake gating into code.
- Distinctive: line 94
Never add or propagate request context unless the user chose scoped rollout.
“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add Feature Flag Skill
You add a runtime feature flag to Sim that can change on prod with no redeploy (AWS AppConfig). Prefer a global on/off flag unless the rollout actually needs per-organization, per-user, or platform-admin targeting. When AppConfig isn't the source of truth, the flag falls back to a single secret (on/off only).
When to use this vs env-flags.ts
- Feature flag (
@/lib/core/config/feature-flags.ts): runtime global on/off by default, optionally scoped byuserId/orgId/admin. This skill. - Env flag (
@/lib/core/config/env-flags.ts): deploy-time capability/environment detection (isProd,isHosted,isBillingEnabled). A module-load boolean. Do not add gated flags here.
If the user wants a fixed per-deployment toggle, send them to env-flags.ts instead.
The flag model
A flag's gating rule lives only in the hosted AppConfig document. It is ON for a context when any configured clause matches:
interface FeatureFlagRule {
enabled?: boolean // global default for everyone
orgIds?: string[] // allowlisted organization ids
userIds?: string[] // allowlisted user ids
adminEnabled?: boolean // platform admins (user.role === 'admin')
}Critically, none of this is expressible in code — gating (especially adminEnabled) can only be set through AppConfig, so no environment can grant access from a code literal. Off-AppConfig (self-hosted/OSS/local), a flag is simply on or off, derived from its fallback secret.
Steps
Confirm the granularity before editing code. If the user has not already specified it, stop and ask:
Should
<flag-name>be a global on/off flag (recommended), or does it need rollout targeting by organization, user, and/or platform admin?- Recommend global. Do not infer scoped gating merely because the call site already has a user or organization id.
- If the user chooses scoped gating but does not name the dimensions, ask which of organization, user, and platform admin it needs. Wire only the selected dimensions.
- If the user wants a fixed per-deployment toggle rather than a runtime AppConfig flag, use
env-flags.tsinstead.
Define the flag. Add one entry to the
FEATURE_FLAGSregistry inapps/sim/lib/core/config/feature-flags.ts. Each entry is the flag's whole definition — name (kebab-case key),description, and thefallbacksecret consulted when AppConfig isn't the source of truth (truthy ⇒ on globally):const FEATURE_FLAGS = { '<flag-name>': { description: '<what this gates>', fallback: '<FLAG_SECRET>', }, }fallbackis the env/secret key (typed askeyof typeof env), so add<FLAG_SECRET>toapps/sim/lib/core/config/env.tsfirst (and the deployment's secret store) — it won't typecheck otherwise. Do not add org/user/admin defaults here — that gating exists only in AppConfig. Adding the entry makes<flag-name>a validFeatureFlagName.Gate the call site at the chosen granularity. For the recommended global mode, pass no context:
import { isFeatureEnabled } from '@/lib/core/config/feature-flags' if (await isFeatureEnabled('<flag-name>')) { // gated behavior }Do not fetch, resolve, or thread through user or organization context solely for a global flag.
For scoped rollout, pass only the dimensions the user selected. Admin status is resolved internally, so ordinary callers pass
userId, not a role:import { isFeatureEnabled } from '@/lib/core/config/feature-flags' if (await isFeatureEnabled('<flag-name>', { userId, orgId })) { // gated behavior }- Organization targeting uses
orgId; user and platform-admin targeting requireuserId. - Missing ids are fine — a clause with no matching id is skipped; with no
userId, the admin clause resolves tofalsewithout a DB read. - Admin routes that already know the caller is an admin may pass
{ userId, isAdmin: true }to skip the role lookup. - Client/UI flags: resolve server-side (in a server component, route, or loader) and pass the boolean down as a prop. There is no client AppConfig.
- Organization targeting uses
- (Prod) configure in AppConfig. The infra
feature-flagsprofile schema is permissive, so a new flag needs no infra change. Operators add the flag to the hostedfeature-flagsdocument usingenabledfor global rollout or only the selectedorgIds/userIds/adminEnabledclauses for scoped rollout, then start asim-<env>-fastdeployment (see the AppConfig runbook in the infra README — same flow asaccess-control). The fallback secret only applies when AppConfig is disabled. - Test. Add a case to
apps/sim/lib/core/config/feature-flags.test.tsthat matches the chosen granularity. For a global flag, exerciseisFeatureEnabled('<flag-name>')with an AppConfigenabledrule and toggle the fallback secret for the off-AppConfig path. For scoped rollout, cover only the selected clauses and mockisPlatformAdminwhen testingadminEnabled. - Clean up after rollout. When the feature ships to everyone, delete the flag's entry from
FEATURE_FLAGS, the<FLAG_SECRET>env entry, the AppConfig document, the call sites, and the test. Leaving dead flags around is the main failure mode of flag systems.
Notes
- Flag keys are
kebab-case. - Never read flags via raw
fetchor a new AppConfig client — always go throughisFeatureEnabled/getFeatureFlags. - Never bake gating into code. The fallback is a single boolean secret; org/user/admin scoping is AppConfig-only.
- Never add or propagate request context unless the user chose scoped rollout.
- The admin check reads the DB replica (
dbReplica) and is resolved lazily, so an admin-gated flag adds at most one cheap replica read, and only whenadminEnabledis the deciding clause.
Other versions9 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- simstudioai/sim★ 30k86% same
Wrote their own version · 8
- warpdotdev/Warp★ 66ksame name
- warpdotdev/warp★ 66ksame name
- OpenCTI-Platform/opencti★ 10ksame name
- zerx-lab/warp★ 2.1ksame name
- zerx-lab/zap★ 2.1ksame name
- dominikmartn/harp★ 698same name
- black12-ag/weft★ 2same name
- okwhrlgma-bit/library★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use add-telemetry, promote-feature and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
zerx-labSkilladd-telemetry
Add telemetry events to track user behavior or system events in the Warp codebase. Use when instrumenting new features, debugging issues, or measuring product metrics.
Also in 6 projects that use this
zerx-labSkillpromote-feature
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.
Also in 6 projects that use this
black12-agSkillchangelog-draft
Generate a reviewable changelog draft from PRs merged in a release range. Extracts explicit CHANGELOG markers, classifies unmarked PRs, adds external contributor attribution, and outputs markdown + JSON artifacts. Does NOT mutate channel_versions.json.
Also in 4 projects that use this
black12-agSkillclassify-changelog-pr
Reference guidance for classifying whether an unmarked PR should appear in the changelog and under which category. Used inline by the changelog-draft skill — not dispatched as a separate agent.
Also in 4 projects that use this
- +3 more from zerx-lab
- +5 more from black12-ag
In this repository54 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/constitution.mdcCursor rule
- .cursor/rules/emcn-components.mdcCursor rule
- .cursor/rules/global.mdcCursor rule
- .cursor/rules/landing-seo-geo.mdcCursor rule
- .cursor/rules/sim-architecture.mdcCursor rule
- .cursor/rules/sim-components.mdcCursor rule
- .cursor/rules/sim-hooks.mdcCursor rule
- .cursor/rules/sim-imports.mdcCursor rule
- .cursor/rules/sim-integrations.mdcCursor rule
- .cursor/rules/sim-queries.mdcCursor rule
- .cursor/rules/sim-sandbox.mdcCursor rule
- .cursor/rules/sim-stores.mdcCursor rule
- .cursor/rules/sim-styling.mdcCursor rule
- .cursor/rules/sim-testing.mdcCursor rule
- .cursor/rules/sim-typescript.mdcCursor rule
- .cursor/rules/sim-ui-copy.mdcCursor rule
- add-block-previewSkill
- add-blockSkill
- add-column-typeSkill
- add-connectorSkill
- add-enrichmentSkill
- add-hosted-keySkill
- add-integrationSkill
- add-managed-cliSkill
- add-modelSkill
- add-toolsSkill
- add-triggerSkill
- babysitSkill
- cleanupSkill
- councilSkill
- db-migrateSkill
- design-taste-frontendSkill
- emcn-design-reviewSkill
- emil-design-engSkill
- make-interfaces-feel-betterSkill
- memory-load-checkSkill
- migrate-application-operationSkill
- react-query-best-practicesSkill
- shipSkill
- tool-registry-boundarySkill
- v2-api-conventionsSkill
- validate-connectorSkill
- validate-integrationSkill
- validate-modelSkill
- validate-triggerSkill
- you-might-not-need-a-callbackSkill
- you-might-not-need-a-commentSkill
- you-might-not-need-a-memoSkill
- you-might-not-need-an-effectSkill
- you-might-not-need-stateSkill
- you-might-not-need-url-stateSkill
- add-settings-pageSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

