Declare, evaluate, manage, and remove framework feature flags. Use when shipping a capability gradually, targeting users or organizations, or replacing a compile-time rollout switch with a production-safe runtime flag.
78
100%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
A feature flag is a boolean declared in app code, evaluated locally by Core, and managed from the Analytics fleet control plane. Code owns whether a flag exists. Runtime settings own only its rollout state.
Flags let an app deploy dormant code and turn it on in the real environment without another deployment. They are not experiments: do not add variants, hypotheses, conversion metrics, exposure tracking, or lifecycle states.
Use a flag for a reversible rollout of a user-facing capability whose dormant code is safe to deploy. Flags are useful for production dogfooding, exact-user or organization pilots, and deterministic percentage rollouts.
Do not use a flag for authentication, authorization, secrets, audit enablement, SSR cache behavior, or another security boundary. Client hiding is presentation only; every guarded server action must evaluate the same registered flag.
Keep definitions in a shared TypeScript module so server and client code use the same stable key. Flags are boolean and default-off.
import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
export const FULL_APP_BUILDING = defineFeatureFlag({
key: "full-app-building",
displayName: "Full app building",
description: "Create and edit Fusion-backed applications.",
});Keys are immutable, never reused, and contain only letters, numbers, dots, underscores, or hyphens. Prefer a concise app-owned name. Do not create flag definitions or rollout rows from Analytics.
Register app definitions from a Nitro plugin before actions are discovered. Do not add app-specific flags to a Core registry.
import { createFeatureFlagsPlugin } from "@agent-native/core/server";
import { FULL_APP_BUILDING } from "../../shared/feature-flags.js";
export default createFeatureFlagsPlugin({ flags: [FULL_APP_BUILDING] });The server action is the enforcement boundary:
import { isFeatureFlagEnabled } from "@agent-native/core/feature-flags";
run: async (args, ctx) => {
if (!(await isFeatureFlagEnabled(FULL_APP_BUILDING, ctx))) {
throw new Error("Full app building is not enabled for this account.");
}
// guarded operation
}Use the client hook only to hide or reveal hydrated UI:
import { useFeatureFlag } from "@agent-native/core/client/feature-flags";
const enabled = useFeatureFlag(FULL_APP_BUILDING.key);
return enabled ? <FullAppOption /> : null;The client hook intentionally returns false while loading or for an unknown flag. Never replace that fail-closed behavior with app-local bucketing or a compile-time fallback. Never evaluate personalized flags in the public SSR shell; it is shared and cached for every visitor.
Core mounts three actions in registered apps:
| Action | Purpose |
|---|---|
get-feature-flags | Return the current caller's evaluated boolean values. |
list-feature-flags | Return definitions and rollout metadata to an authorized operator. |
set-feature-flag | Atomically turn a flag off, enable it for the operator, or replace targeting rules. |
Analytics calls the app-local operator actions through narrowly scoped A2A delegation. Tokens require an exact audience, organization, scope, operator role, and audit correlation id. Management is permission-checked and audited by the target app. Never manage flags through generic settings routes, raw SQL, or per-app toggle UIs.
The operator modes are Off, Targeted, and Everyone. Core stores them
as off, rules, and on.
Targeted rules combine exact normalized emails, exact organization IDs, and a percentage with OR semantics. Exact matches are checked first. Percentage buckets use Core's stable hash of the flag key and authenticated user identity; anonymous callers fail closed. Raising a percentage preserves the users already included at a lower percentage. Do not implement bucketing in app code.
Unknown definitions, missing state, malformed state, storage errors, and
evaluation errors all return the code default (false in v1). Explicit Off
wins over every target; Everyone enables every authenticated caller.
After a rollout is permanent:
A permanent flag is just an if statement with a pension plan.
AGENTS.md, and
pnpm guard:workspace-skills passes after syncing generated copies.c1ee18b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.