Skills feature-flag-manager

install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/feature-flag-manager" ~/.claude/skills/terminalskills-skills-feature-flag-manager && rm -rf "$T"
manifest: skills/feature-flag-manager/SKILL.md
source content

Feature Flag Manager

Overview

Implements feature flag systems for controlled rollouts and A/B testing. Covers flag definition, deterministic user bucketing (same user always sees the same variant), attribute-based targeting, percentage rollouts, and flag lifecycle management. Builds self-hosted solutions — no third-party dependencies.

Instructions

1. Flag Definition Schema

interface FeatureFlag {
  key: string;              // "checkout-redesign"
  type: 'boolean' | 'multivariate';
  enabled: boolean;         // Global kill switch
  variants: string[];       // ["control", "new-checkout"]
  allocation: number[];     // [50, 50] — percentage per variant
  targeting?: TargetingRule[];
  createdAt: Date;
  updatedAt: Date;
}

interface TargetingRule {
  attribute: string;        // "plan", "country", "signupDate"
  operator: 'eq' | 'neq' | 'in' | 'gt' | 'lt' | 'contains';
  values: any[];
  allocation?: number[];    // Override allocation for this segment
}

Store flags in database with in-memory cache (refresh every 30 seconds or on webhook).

2. Deterministic Bucketing

Use MurmurHash3 for stable, uniform distribution:

import murmurhash from 'murmurhash';

function assignVariant(flagKey: string, userId: string, variants: string[], allocation: number[]): string {
  const hash = murmurhash.v3(flagKey + ':' + userId);
  const bucket = hash % 10000; // 0-9999 for 0.01% granularity
  
  let cumulative = 0;
  for (let i = 0; i < variants.length; i++) {
    cumulative += allocation[i] * 100; // Convert percentage to basis points
    if (bucket < cumulative) return variants[i];
  }
  return variants[0]; // Fallback to first variant
}

Properties:

  • Deterministic: Same user + same flag = same variant, always
  • Independent: Different flags produce independent assignments
  • Uniform: MurmurHash3 distributes evenly across buckets
  • Stable on resize: Changing 50/50 to 70/30 keeps most users in their original bucket

3. Flag Evaluation Pipeline

evaluateFlag(flagKey, userId, userAttributes):
  1. Load flag config from cache
  2. If flag.enabled === false → return default variant (control)
  3. Check targeting rules in order:
     - If user matches a rule → use that rule's allocation
     - If no rules match → use default allocation
  4. Compute bucket via deterministic hash
  5. Map bucket to variant via allocation percentages
  6. Log assignment event (for analytics)
  7. Return variant name

4. Server-Side Integration

// Express middleware — evaluate all active flags per request
app.use((req, res, next) => {
  const userId = req.user?.id || req.cookies.anonymousId;
  const attributes = {
    plan: req.user?.plan,
    country: req.headers['cf-ipcountry'],
    signupDate: req.user?.createdAt,
  };
  req.flags = evaluateAllFlags(userId, attributes);
  next();
});

// In route handler
app.get('/checkout', (req, res) => {
  if (req.flags['checkout-redesign'] === 'new-checkout') {
    return renderNewCheckout(req, res);
  }
  return renderCurrentCheckout(req, res);
});

5. Flag Lifecycle

1. CREATED — Flag defined, enabled=false, no traffic
2. TESTING — Enabled for internal users via targeting (email contains @company.com)
3. RAMPING — Gradual rollout: 5% → 25% → 50% → 100%
4. DECIDED — Experiment concluded, winner at 100%
5. ARCHIVED — Flag code removed, config kept for audit trail

Track lifecycle in database. Alert when flags are in DECIDED state for > 14 days (cleanup reminder).

6. Admin API

GET    /api/flags                    — List all flags
POST   /api/flags                    — Create flag
PATCH  /api/flags/:key               — Update allocation/targeting
PATCH  /api/flags/:key/toggle        — Enable/disable (kill switch)
GET    /api/flags/:key/assignments   — View user distribution
DELETE /api/flags/:key               — Archive flag

Examples

Example 1: Boolean Feature Flag

Prompt: "Add a feature flag for our new search bar. Roll out to 10% of users first."

Output: Flag definition with boolean type, 90/10 allocation, evaluation middleware, and admin toggle endpoint.

Example 2: Multi-Variant Experiment

Prompt: "Test three pricing page layouts: current, simplified, and detailed. Only for US users on free plan."

Output: Multivariate flag with targeting rules (country=US, plan=free), three-way allocation (34/33/33), bucketing implementation, and assignment logging for analytics.

Guidelines

  • Always use server-side evaluation — client-side flags leak experiment details and flicker
  • Hash with experiment key — ensures independent randomization across experiments
  • Cache flag configs — don't query database on every request; 30s TTL is fine
  • Log every assignment — needed for experiment analysis; include flag, variant, userId, timestamp
  • Build a kill switch
    enabled: false
    must immediately disable the flag globally
  • Clean up old flags — stale flags become tech debt; alert after 14 days post-decision
  • Test the bucketing — verify distribution is uniform with 10K+ simulated users before shipping
  • Support anonymous users — use a cookie-based anonymous ID for pre-login bucketing