gerrit-create
Use when creating or updating Gerrit changes — pushing code for review, amending patch sets, setting reviewers and topics.…
This skill should be used when the user asks to "add a feature flag", "gate a feature", "put this behind a flag", "add a workspace flag", "feature flag this", "make this configurable per workspace", "configure Unleash", or references "flags.json", "useWorkspaceFlag", "useFlag",
$ npx -y skills add ambient-code/platform --skill unleash-flag --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/unleash-flagContext preview
The summary Claude sees to decide when to auto-load this skill.
This skill should be used when the user asks to "add a feature flag", "gate a feature", "put this behind a flag", "add a workspace flag", "feature flag this", "make this configurable per workspace", "configure Unleash", or references "flags.json", "useWorkspaceFlag", "useFlag",
name: unleash-flag description: This skill should be used when the user asks to "add a feature flag", "gate a feature", "put this behind a flag", "add a workspace flag", "feature flag this", "make this configurable per workspace", "configure Unleash", or references "flags.json", "useWorkspaceFlag", "useFlag", "SyncFlags", or "controlled rollout" of a feature.
Workspace-scoped feature flags for the Ambient Code Platform — naming, gating, evaluation, and lifecycle management.
Every new flag requires these steps. Skip none.
1. **Define the flag** in `components/manifests/base/core/flags.json` 2. **Gate the frontend** using the correct hook for scope 3. **Update tests** to mock the flag hook 4. **Verify** type-check and tests pass
Add to `components/manifests/base/core/flags.json`:
{
"name": "category.feature-name.enabled",
"description": "Human-readable purpose of this flag",
"tags": [
{
"type": "scope",
"value": "workspace"
}
]
}**All new flags** must use the `category.feature-name.enabled` format:
category.feature-name.enabled
| Segment | Rules | Examples | |---------|-------|---------| | `category` | One of the standard categories below | `runner`, `model`, `integration` | | `feature-name` | Lowercase, hyphen-separated, descriptive | `gemini-cli`, `coderabbit` | | `.enabled` | Required suffix for all new flags | — |
**Standard categories:**
| Category | When | Example | |----------|------|---------| | `integration` | External service integrations | `integration.coderabbit.enabled` | | `runner` | Runner type availability | `runner.gemini-cli.enabled` | | `model` | Model availability (auto-generated by SyncFlags) | `model.claude-sonnet-4-5.enabled` | | `feature` | Platform capabilities | `feature.scheduled-export.enabled` |
**Grandfathered flags** (do not rename):
These predate the convention. New flags must not follow their patterns.
**Rules:**
The `scope:workspace` tag is what makes a flag appear in the workspace settings UI. Without it, the flag exists in Unleash but workspace admins cannot toggle it.
Backend `SyncFlags` runs at startup: reads `flags.json`, creates flags in Unleash (type: `release`, disabled by default, 0% rollout), and tags them. Flags without `EnabledByDefault: true` start **off**.
To force a re-sync, restart the backend. To clear a stuck flag, archive + purge it in Unleash admin before restarting.
**Default: `useWorkspaceFlag`** — always prefer this hook. It respects ConfigMap overrides set by workspace admins.
import { useWorkspaceFlag } from "@/services/queries/use-feature-flags-admin";
const { enabled } = useWorkspaceFlag(projectName, "category.feature.enabled");**Exception: `useFlag`** — only for the rare case where no project context is available (e.g., cluster-level admin pages like `/integrations`). It bypasses workspace overrides entirely and returns only the Unleash global default. Do not use it in project-scoped pages.
import { useFlag } from "@/lib/feature-flags";
const enabled = useFlag("category.feature.enabled");| Hook | Scope | Evaluation | |------|-------|------------| | `useWorkspaceFlag` | Project-scoped pages (default) | ConfigMap override > Unleash default | | `useFlag` | Cluster-scoped pages only (exception) | Unleash default only |
**Conditionally render a component:**
const { enabled: featureEnabled } = useWorkspaceFlag(projectName, "category.feature.enabled");
// In JSX:
{featureEnabled && <FeatureComponent />}**Conditionally include in an array:**
const items = [
{ key: "always-visible", name: "Always" },
...(featureEnabled
? [{ key: "gated", name: "Gated Feature" }]
: []),
];**Extract project name from route params** (when not passed as prop):
import { useParams } from "next/navigation";
const params = useParams();
const projectName = params.name as string;For full-stack gating (not always necessary — frontend-only is often sufficient):
// Global check
if !FeatureEnabled("category.feature.enabled") {
c.JSON(http.StatusForbidden, gin.H{"error": "Feature not enabled"})
return
}
// Request-scoped (includes user/IP context for Unleash strategies)
if !FeatureEnabledForRequest(c, "category.feature.enabled") {
c.JSON(http.StatusForbidden, gin.H{"error": "Feature not enabled"})
return
}For endpoints that should be entirely hidden behind a flag, create a middleware in `routes.go` that checks `FeatureEnabledForRequest()` and returns 404 when the flag is off:
// routes.go — gate an entire route group
flagged := router.Group("/api/v1/feature")
flagged.Use(func(c *gin.Context) {
if !handlers.FeatureEnabledForRequest(c, "category.feature.enabled") {
c.AbortWithStatus(http.StatusNotFound)
return
}
c.Next()
})
{
flagged.GET("/resource", handlers.ListResource)
flagged.POST("/resource", handlers.CreateResource)
}This returns 404 (not 403) when the flag is off, so the endpoint appears not to exist. Use this for features that shouldn't even be discoverable until enabled.
When writing E2E tests for flagged features, the Unleash admin token must be set as an environment variable. **Never paste or export the token inline in a shell session** — this
Kubernetes-native AI automation platform for intelligent agentic sessions
Use when creating or updating Gerrit changes — pushing code for review, amending patch sets, setting reviewers and topics.…
Use when reviewing a Gerrit change — fetching change details, reading diffs, posting inline comments, and voting with labels.…
Use when submitting or preparing a Gerrit change for merge — checking submit requirements, rebasing, resolving comments, and…
Run a convention alignment check across the codebase to measure adherence to documented standards. Use when you want to check…
Perform a comprehensive code review using repository-specific standards. Use when reviewing code changes, checking PR quality,…
Perform any development work on the ambient-ui component. Full workflow instructions.