К основному содержанию
скилл CX Codex

feature-flags · bagelhole — скилл для Claude Code: фиче-флаги и раскатка

Скилл для ИИ-агента, который помогает внедрять фиче-флаги: постепенная раскатка, A/B-тесты, kill switch. Пригодится, когда релиз нужно отделить от деплоя.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill feature-flags -a claude-code
Открыть на GitHub

Что делает feature-flags

Скилл описывает пять типов флагов: release, experiment, ops, permission и kill switch. Для каждого — своя задача, от включения новой формы оплаты до аварийного отключения сторонней интеграции. Агент подскажет, какой тип брать под конкретный случай.

Внутри — готовые примеры под LaunchDarkly и Unleash. Для LaunchDarkly это SDK на Node.js и React, правила таргетинга по email, тарифу и проценту раскатки. Для Unleash — docker-compose.yml с сервером и Postgres, клиент на Node.js и стратегии вроде gradualRolloutUserId и flexibleRollout. Есть и вариант без вендора: таблица флагов в Django с процентной раскаткой через хеш от flag_name:user_id, плюс хранение конфигов в Redis.

Для LaunchDarkly нужен ключ SDK в переменной окружения, для Unleash — запущенный сервер и токен API. Процент раскатки считается по хешу, поэтому один и тот же пользователь попадает в одну и ту же группу — это повод проверить, что смена соли не перекинет людей между вариантами посреди эксперимента.

Какие задачи решает

  • включить новую форму оплаты только части пользователей
  • сравнить два варианта кнопки на живом трафике
  • выключить стороннюю интеграцию без нового деплоя
  • дать премиум-функции отдельным тарифам
  • перейти на trunk-based development без долгих веток

Примеры запросов агенту

  • Добавь фиче-флаг new-checkout через LaunchDarkly, включи его для тарифа premium
  • Настрой постепенную раскатку на 25 процентов пользователей через Unleash
  • Сделай kill switch для интеграции с платёжным провайдером

Как установить feature-flags

1Через Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill feature-flags -a claude-code

2Вручную: положить файлы

~/.claude/skills/feature-flags/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/feature-flags/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о feature-flags

Как установить feature-flags в Claude?

Выполни npx skills add BagelHole/DevOps-Security-Agent-Skills --skill feature-flags -a claude-code. Скилл появится в ~/.claude/skills/feature-flags/SKILL.md.

Что делает скилл feature-flags?

Помогает агенту внедрять фиче-флаги: постепенную раскатку, A/B-тесты, управление жизненным циклом флагов и аварийное отключение функций.

Какие сервисы поддерживаются?

LaunchDarkly и Unleash, а также самописные решения на Django и Redis. Для LaunchDarkly нужен ключ SDK, для Unleash — запущенный сервер и токен API.

Исходный текст

SKILL.md · MIT
---
name: feature-flags
description: Implement feature flags for progressive feature rollout using LaunchDarkly, Unleash, or custom solutions. Control feature visibility, perform A/B testing, and enable trunk-based development. Use when implementing gradual rollouts, feature toggles, or experimentation platforms.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# Feature Flags

Control feature releases and enable progressive rollout with feature flag systems.

## When to Use This Skill

Use this skill when:
- Implementing gradual feature rollouts
- Enabling trunk-based development
- Running A/B tests and experiments
- Managing feature lifecycles
- Implementing kill switches for production

## Prerequisites

- Application code access
- Feature flag service or self-hosted solution
- Basic understanding of deployment patterns

## Feature Flag Types

| Type | Purpose | Example |
|------|---------|---------|
| Release | Control feature visibility | New checkout flow |
| Experiment | A/B testing | Button color test |
| Ops | Runtime configuration | Rate limiting |
| Permission | User access control | Premium features |
| Kill Switch | Emergency disable | Third-party integration |

## LaunchDarkly

### SDK Setup (Node.js)

```javascript
const LaunchDarkly = require('launchdarkly-node-server-sdk');

const client = LaunchDarkly.init(process.env.LAUNCHDARKLY_SDK_KEY);

await client.waitForInitialization();

// Evaluate flag
const user = {
  key: 'user-123',
  email: '[email protected]',
  custom: {
    plan: 'premium',
    company: 'acme'
  }
};

const showNewFeature = await client.variation('new-checkout', user, false);

if (showNewFeature) {
  // New feature code
} else {
  // Existing code
}
```

### React SDK

```javascript
import { withLDProvider, useFlags, useLDClient } from 'launchdarkly-react-client-sdk';

// Provider setup
export default withLDProvider({
  clientSideID: 'your-client-side-id',
  user: {
    key: 'user-123',
    email: '[email protected]'
  }
})(App);

// Using flags in component
function FeatureComponent() {
  const { newCheckout, experimentVariant } = useFlags();
  const ldClient = useLDClient();

  // Track events
  const handleClick = () => {
    ldClient.track('checkout-started');
  };

  if (newCheckout) {
    return <NewCheckout onClick={handleClick} />;
  }
  return <OldCheckout onClick={handleClick} />;
}
```

### Targeting Rules

```yaml
# LaunchDarkly targeting configuration
flag: new-checkout
targeting:
  # Individual users
  targets:
    - variation: true
      values: ['user-123', 'user-456']
  
  # Rules
  rules:
    # Beta users
    - variation: true
      clauses:
        - attribute: email
          op: endsWith
          values: ['@company.com']
    
    # Premium plan
    - variation: true
      clauses:
        - attribute: plan
          op: in
          values: ['premium', 'enterprise']
    
    # Percentage rollout
    - variation: true
      rollout:
        variations:
          - variation: true
            weight: 20000  # 20%
          - variation: false
            weight: 80000  # 80%
  
  # Default
  fallthrough:
    variation: false
```

## Unleash

### Server Setup

```yaml
# docker-compose.yml
version: '3.8'

services:
  unleash:
    image: unleashorg/unleash-server:latest
    ports:
      - "4242:4242"
    environment:
      - DATABASE_URL=postgres://postgres:password@db/unleash
      - DATABASE_SSL=false
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=unleash
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:
```

### SDK Setup (Node.js)

```javascript
const { initialize } = require('unleash-client');

const unleash = initialize({
  url: 'http://localhost:4242/api',
  appName: 'my-app',
  customHeaders: {
    Authorization: 'your-api-token'
  }
});

unleash.on('ready', () => {
  // Check feature
  const isEnabled = unleash.isEnabled('new-checkout');
  
  // With context
  const context = {
    userId: 'user-123',
    properties: {
      plan: 'premium'
    }
  };
  
  const isEnabledForUser = unleash.isEnabled('new-checkout', context);
  
  // Get variant
  const variant = unleash.getVariant('experiment-flag', context);
  console.log(variant.name); // 'control' or 'treatment'
});
```

### Activation Strategies

```yaml
# Standard strategies
strategies:
  - name: default
    # On/off for everyone
    
  - name: userWithId
    parameters:
      userIds: 'user-1,user-2,user-3'
    
  - name: gradualRolloutUserId
    parameters:
      percentage: 25
      groupId: 'new-feature'
    
  - name: gradualRolloutRandom
    parameters:
      percentage: 50
    
  - name: flexibleRollout
    parameters:
      rollout: 30
      stickiness: userId
      groupId: 'checkout-exp'
```

## Custom Implementation

### Database-Backed Flags

```python
# models.py
from django.db import models

class FeatureFlag(models.Model):
    name = models.CharField(max_length=100, unique=True)
    enabled = models.BooleanField(default=False)
    rollout_percentage = models.IntegerField(default=0)
    allowed_users = models.JSONField(default=list)
    rules = models.JSONField(default=dict)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

# service.py
import hashlib

class FeatureFlagService:
    def __init__(self):
        self._cache = {}
    
    def is_enabled(self, flag_name, user_id=None, context=None):
        flag = self._get_flag(flag_name)
        
        if not flag or not flag.enabled:
            return False
        
        # Check user allowlist
        if user_id and user_id in flag.allowed_users:
            return True
        
        # Check rules
        if context and self._evaluate_rules(flag.rules, context):
            return True
        
        # Check percentage rollout
        if flag.rollout_percentage > 0 and user_id:
            return self._is_in_rollout(flag_name, user_id, flag.rollout_percentage)
        
        return flag.rollout_percentage == 100
    
    def _is_in_rollout(self, flag_name, user_id, percentage):
        hash_input = f"{flag_name}:{user_id}"
        hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16)
        return (hash_value % 100) < percentage
    
    def _evaluate_rules(self, rules, context):
        for rule in rules.get('rules', []):
            if self._evaluate_rule(rule, context):
                return True
        return False
```

### Redis-Backed Flags

```python
import redis
import json

class RedisFeatureFlags:
    def __init__(self, redis_url):
        self.redis = redis.from_url(redis_url)
        self.prefix = 'feature_flag:'
    
    def set_flag(self, name, config):
        key = f"{self.prefix}{name}"
        self.redis.set(key, json.dumps(config))
    
    def is_enabled(self, name, user_id=None):
        key = f"{self.prefix}{name}"
        data = self.redis.get(key)
        
        if not data:
            return False
        
        config = json.loads(data)
        
        if not config.get('enabled', False):
            return False
        
        # User allowlist
        if user_id in config.get('users', []):
            return True
        
        # Percentage rollout
        percentage = config.get('percentage', 0)
        if percentage == 100:
            return True
        
        if percentage > 0 and user_id:
            return self._hash_user(name, user_id) < percentage
        
        return False
    
    def _hash_user(self, flag, user_id):
        import hashlib
        hash_input = f"{flag}:{user_id}"
        return int(hashlib.sha256(hash_input.encode()).hexdigest(), 16) % 100
```

## Testing with Feature Flags

### Unit Testing

```javascript
// Jest mocking
jest.mock('launchdarkly-node-server-sdk', () => ({
  init: jest.fn(() => ({
    waitForInitialization: jest.fn().mockResolvedValue(undefined),
    variation: jest.fn()
  }))
}));

describe('Checkout', () => {
  it('shows new checkout when flag enabled', async () => {
    const ldClient = require('launchdarkly-node-server-sdk').init();
    ldClient.variation.mockResolvedValue(true);
    
    const result = await renderCheckout(user);
    expect(result).toContain('NewCheckout');
  });
  
  it('shows old checkout when flag disabled', async () => {
    const ldClient = require('launchdarkly-node-server-sdk').init();
    ldClient.variation.mockResolvedValue(false);
    
    const result = await renderCheckout(user);
    expect(result).toContain('OldCheckout');
  });
});
```

### Integration Testing

```python
# pytest fixtures
import pytest

@pytest.fixture
def feature_flags():
    """Provide controllable feature flags for testing."""
    flags = {}
    
    class TestFlags:
        def set(self, name, value):
            flags[name] = value
        
        def is_enabled(self, name, **kwargs):
            return flags.get(name, False)
    
    return TestFlags()

def test_new_checkout(feature_flags):
    feature_flags.set('new-checkout', True)
    
    response = client.get('/checkout')
    assert 'new-checkout-form' in response.content
```

## Monitoring and Analytics

### Flag Usage Tracking

```javascript
// Track flag evaluations
const flagMetrics = {
  evaluations: new Map(),
  
  track(flagName, variation, user) {
    const key = `${flagName}:${variation}`;
    const count = this.evaluations.get(key) || 0;
    this.evaluations.set(key, count + 1);
    
    // Send to analytics
    analytics.track('feature_flag_evaluated', {
      flag: flagName,
      variation: variation,
      userId: user.key
    });
  }
};
```

### Stale Flag Detection

```python
from datetime import datetime, timedelta

def detect_stale_flags():
    """Find flags that haven't been evaluated recently."""
    stale_threshold = timedelta(days=30)
    now = datetime.utcnow()
    
    stale_flags = []
    for flag in FeatureFlag.objects.all():
        if flag.last_evaluated:
            age = now - flag.last_evaluated
            if age > stale_threshold:
                stale_flags.append({
                    'name': flag.name,
                    'last_evaluated': flag.last_evaluated,
                    'age_days': age.days
                })
    
    return stale_flags
```

## Common Issues

### Issue: Inconsistent Flag Evaluation
**Problem**: Same user sees different variations
**Solution**: Use consistent hashing, check caching strategy

### Issue: Flag Debt Accumulation
**Problem**: Too many old flags in codebase
**Solution**: Implement flag lifecycle, regular cleanup sprints

### Issue: Performance Impact
**Problem**: Flag evaluation slowing requests
**Solution**: Use local caching, batch evaluations

## Best Practices

- Use consistent naming conventions
- Document flag purpose and owner
- Set expiration dates for temporary flags
- Implement flag lifecycle management
- Use gradual rollouts (not 0→100)
- Monitor flag evaluation metrics
- Clean up old flags regularly
- Test both variations in CI

## Related Skills

- [blue-green-deploy](../blue-green-deploy/) - Deployment strategies
- [git-workflow](../git-workflow/) - Trunk-based development
- [alerting-oncall](../../observability/alerting-oncall/) - Monitoring rollouts

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Похожие скиллы

Всё по теме «DevOps и инфраструктура» →

Сначала — feature-flags от других авторов.

feature-flags react Скилл для работы с фича-флагами в репозитории React: подсказывает, где живут флаги, как гейтить тесты и почему падает конкретный канал. CX Codex +1 1 200установок feature-flags-architect claude-code-skills Ведёт фиче-флаги по циклу: завести, раскатить, погасить. Пригодится, когда флаги копятся и никто не помнит, какие ещё живы. 469установок adding-feature-flags spencerpauly Настраивает фиче-флаги для поэтапного выката функций и A/B-тестирования через PostHog или переменные окружения. CX Codex +1 361установок launchdarkly-flag-targeting launchdarkly Скилл для управления таргетингом фича-флагов LaunchDarkly: включение, процентные раскатки, правила и отдельные пользователи. CX Codex +1 4 100установок launchdarkly-metric-choose launchdarkly Помогает выбрать метрики для эксперимента, guarded rollout или release policy в LaunchDarkly и показывает, что уже подцепится автоматически. CX Codex +1 3 200установок cleaning-up-stale-feature-flags PostHog Находит устаревшие фича-флаги в проекте PostHog и убирает код, который их проверяет. Пригодится, когда флагов накопилось много и непонятно, какие уже можно удалить. CX Codex +1 434установок auditing-experiments-flags PostHog Проверяет эксперименты и фича-флаги PostHog на ошибки конфигурации, устаревание и нарушения практик. Пригодится перед тем, как доверять результатам A/B-теста. CX Codex +1 432установок

Из того же набора127

change-management Скилл задаёт регламенты управления изменениями в проде, правила для комитета CAB и шаблоны запросов. Пригодится при подготовке к аудитам SOC 2 или ITIL. CX Codex +1 329установок startup-it-troubleshooting Набор готовых команд для тех, кто тянет IT в стартапе без выделенного админа: сброс паролей, Wi-Fi, VPN, место на диске. CX Codex +1 330установок loki-logging Скилл помогает настроить Grafana Loki, Promtail и запросы LogQL прямо в проекте, без похода в документацию. CX Codex +1 330установок aws-vpc Разворачивает трёхуровневую сеть в AWS с публичными, приватными и изолированными подсетями. Пригодится при настройке сетевой инфраструктуры через CLI. CX Codex +1 328установок gcp-compute Скилл помогает развёртывать виртуальные машины Compute Engine в Google Cloud, собирать группы инстансов и настраивать Spot VM через CLI и Terraform. CX Codex +1 328установок gpu-kubernetes-operations Скилл для работы с GPU-кластерами Kubernetes: планирование подов, MIG-разделение, автоскейлинг и мониторинг через DCGM. CX Codex +1 329установок fedramp-compliance Скилл для команд, которые готовят облачный сервис к FedRAMP: раскладывает требования по уровням воздействия и семьям контролей NIST 800-53. CX Codex +1 328установок llm-app-security Набор проверок и правил для защиты чат-ботов, RAG-систем и AI-функций от инъекций промптов, утечек данных и атак по классификации OWASP LLM Top 10. CX Codex +1 327установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой