Skip to content
Skills Library
Programming · Building & coding

runtime-feature-flags

/runtime-feature-flags

Add, roll out, promote, graduate, or remove Kandev runtime feature flags and release toggles across the backend and frontend. Use whenever a task mentions a feature flag, release toggle, staged rollout, kill switch, or graduating a flag.

Author
kdlbs ↗
Repository
kandev ↗
Licence
AGPL-3.0
Last repository change
27.10.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 27.10.2026, without references to retired models or APIs.

Licence

AGPL-3.0, copyleft: przeróbki udostępniane innym muszą mieć tę samą licencję.

What it does and when to use it

Add, roll out, promote, graduate, or remove Kandev runtime feature flags and release toggles across the backend and frontend. Use whenever a task mentions a feature flag, release toggle, staged rollout, kill switch, or graduating a flag.

Original author description

Add, roll out, promote, graduate, or remove Kandev runtime feature flags and release toggles across the backend and frontend. Use whenever a task mentions a feature flag, release toggle, staged rollout, kill switch, or graduating a flag.

How it works

  1. Invariants
  2. Add a flag
  3. Roll out and promote
  4. Graduate and remove the flag
  5. Verification and handoff
Original SKILL.md headings · 110 lines, 747 words
SKILL.md preview
---
name: runtime-feature-flags
description: Add, roll out, promote, graduate, or remove Kandev runtime feature flags and release toggles across the backend and frontend. Use whenever a task mentions a feature flag, release toggle, staged rollout, kill switch, or graduating a flag.
---

# Runtime Feature Flags

Use this checklist for temporary release toggles and risky features. It is
self-contained: do not depend on the agent having read an ADR or public docs.
Read `apps/backend/AGENTS.md` and `apps/web/AGENTS.md` when the change touches
those subtrees.

## Invariants

- The backend is authoritative. A disabled feature must not be reachable through
  HTTP, WebSocket, MCP, agent-tool, or background-job entry points.
- A new release toggle is off in every shipped profile when it is merged. The
  disabled path preserves the existing behavior and fails closed before deriving
  data, writing state, dispatching work, or exposing a capability.
- Effective values are ordered: explicit environment variable, SQLite override,
  then profile default. An explicit environment variable locks the admin UI.
- Use one identity across layers: `features.<camelCaseKey>`,
  `KANDEV_FEATURES_<UPPER_SNAKE_CASE>`, a Go `FeaturesConfig` field, its JSON tag,
  and the matching frontend key. Never add a parallel flag map or switch.
- Never reuse an identity recorded in the repository's append-only retired
  registry. Before relying on retirement, verify that `retiredRuntimeFlagIdentities`
  and its collision/completeness test exist; if they do not, add that
  runtimeflags infrastructure before removing a live flag.

## Add a flag

Update these layers in the same change:

1. **Profile default:** add `KANDEV_FEATURES_<NAME>` under `features:` in the
   root `profiles.yaml`; use `prod: "false"`, `dev: "false"`, and `e2e: "false"`
   for a release toggle unless the task explicitly documents a test-only
   exception.
2. **Backend config:** add a `bool` field with explicit `mapstructure` and
   `json` tags to `apps/backend/internal/common/config/config.go`.
3. **Registry/config binding:** add exactly one metadata registration to
   `apps/backend/internal/runtimeflags/registry.go`: key, env var, kind, label,
   description, stability, risk, and restart/mutability metadata. The registry
   definition is metadata-only; add the key/env constants and update
   `OptionsFromConfig`, `ValuesFromConfig`, and `ApplyStatesToConfig` in
   `runtimeflags/config.go` for typed config wiring.
4. **Backend gates:** gate construction and every enabled-only entry path at the
   narrow composition boundary. Do not only hide the frontend; direct callers
   must receive the legacy behavior or a safe rejection.
5. **Frontend contract:** add the all-off key to
   `apps/web/lib/state/slices/features/types.ts`. Use `useFeature()` for client
   surfaces and `notFound()` from the relevant server layout/page when a route
   subtree must be unavailable. SSR data must remain fail-closed.
6. **Tests:** add enabled/disabled behavior tests for each changed backend path
   and frontend surface. Run the existing registry/profile/frontend contract
   tests; add focused tests for normalization, route visibility, and disabled
   side-effect prevention where applicable.

The completeness checks require exact equality between profile keys, typed
backend fields/registrations, and frontend default keys. They do not discover
semantic call sites, so trace the feature's HTTP, WebSocket, MCP, agent, worker,
and startup paths manually.

## Roll out and promote

1. Merge with all shipped profile defaults off.
2. Enable one installation through **Settings > System > Feature Toggles** or an
   explicit environment variable, restart when metadata requires it, and test
   real workflows.
3. When ready for everyone, change only the `prod` profile value to `"true"` for
   the next release. Retain the registry entry and backend/frontend gates as a
   kill switch so operators can still disable the feature.

## Graduate and remove the flag

After the feature has proven itself as the default-on behavior, make the new
behavior unconditional and remove the live flag end-to-end:

- remove the profile entry and `FeaturesConfig` field;
- remove the active registry registration;
- remove backend conditionals and legacy branches;
- remove the frontend default, `useFeature()` checks, and route gates;
- remove flag-specific tests and documentation while keeping permanent behavior
  coverage.

Before removing the registration, verify the append-only
`retiredRuntimeFlagIdentities` registry and its collision/completeness test
exist, then append the exact key and environment variable in `registry.go`:

```go
{key: "features.example", envVar: "KANDEV_FEATURES_EXAMPLE"},
```

Do not delete old `runtime_flag_overrides` rows as part of graduation. Unknown
rows are intentionally inert, and the retired identity prevents stale operator
state from reactivating a future feature. Never reuse either the key or env var.

## Verification and handoff

Run the focused checks appropriate to the change:

- In a fresh worktree, run `pnpm install --frozen-lockfile` from `apps/` before
  any pnpm-based checks, tests, lint, or commits.
- from `apps/backend`: `go test ./internal/runtimeflags ./internal/common/config ./internal/profiles`;
- from the repository root: `bash scripts/lint-go-changed <changed-go-files>`,
  following `apps/backend/AGENTS.md` for comparison-base and resource defaults;
- from `apps`: `pnpm --filter @kandev/web test -- lib/state/slices/features/features-contract.test.ts`;
- from `apps/web`: `pnpm run typecheck` and `pnpm run lint`;
- run affected E2E coverage when the gated surface is user-visible;
- run `git diff --check` before handoff.

Report the flag key/env identity, profile defaults, every gated entry path,
disabled/enabled test evidence, restart requirements, and whether the change is
still a kill switch or has been fully graduated.

Versions

The database has no other skills named runtime-feature-flags.

Database snapshot: 13.11.2026 · package version 19860ed9169b (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100057-design-feature-toggles
    Use when designing, implementing, reviewing, testing, or cleaning up feature toggles, feature flags, kill switches, runtime configuration gates, canary controls, staged rollouts, experiments, or temporary compatibility switches in Java enterprise systems. This should trigger for…
  • 90add-feature-flag
    Use when a ticket asks to ship behaviour behind a toggle — a gradual rollout, a kill switch, an A/B variant, a dark launch — or to add, wire, or clean up a feature flag with a default, an owner, and a removal plan. Invoke for "put it behind a flag", "add a kill switch", "roll…
  • 100launchdarkly
    LaunchDarkly is a hosted feature flag service: it evaluates flags in your app so you can roll features out gradually, target segments and switch features off without a deploy. Use when a user asks to implement feature flags, roll out features gradually, run an A/B test, control…
  • 90backend-feature-flags
    Use this skill when implementing feature flags, canary releases, A/B testing, or kill switches. This skill enforces: flag ownership with removal date, cached evaluation, kill switches for critical features, safe defaults (off). Applies to LaunchDarkly, Unleash, Flagsmith, or…
  • 100feature-flags-engineering
    Engineering practice: Feature flags — Ship code dark, roll it out in stages, switch it off in seconds, and delete the flag once the rollout is done. Use in any language or framework whenever this practice applies, and when reviewing work that should follow it.
  • 100feature-flags-authoring
    Add, edit, or remove a Packmind feature flag across the shared registry, the frontend gate, and the backend helper. Use when the user wants to create a new feature flag, gate a feature behind a flag, open or restrict a flag to a domain/email, change a flag audience, retire or…

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.