AgentSkillsCN

feature-flag-management

按照Epic 10卫生标准,在Saberloop中实现功能标志的全生命周期自动化。

SKILL.md
--- frontmatter
name: feature-flag-management
description: Automate the complete lifecycle of feature flags in Saberloop, following Epic 10 hygiene standards
version: 1.0.0
author: Saberloop Project
usage: |
  Use this skill when working with feature flags:
  - Creating new feature flags for gradual rollout
  - Updating flag phases (DISABLED → SETTINGS_ONLY → ENABLED)
  - Removing deprecated flags following hygiene standards
  - Adding flag documentation
  
  Examples:
  "Create a new FEATURE_NAME flag using the feature-flag-management skill"
  "Remove the OLD_FEATURE flag using the feature-flag-management skill"
  "Update FEATURE_NAME to SETTINGS_ONLY phase using the feature-flag-management skill"

# Feature Flag Management Skill

## Overview

This skill automates the complete lifecycle of feature flags in Saberloop, following the established patterns from Epic 10 hygiene processes.

## Flag Lifecycle

```
DISABLED → SETTINGS_ONLY → ENABLED → REMOVED
```

### Phase Definitions

| Phase | Description | User Visibility | Typical Duration |
|

-----|-------------|------------------|------------------| | DISABLED | Code deployed but inactive | None | Testing phase | | SETTINGS_ONLY | Available in Settings page only | Settings page | User testing | | ENABLED | Available everywhere | Full app | Production |

When to Create a Flag

Create a flag when ALL of these are true:

  • New feature needs gradual rollout
  • Feature is risky and might need quick rollback
  • Feature will be A/B tested
  • Rollout plan exists with success metrics

When to Remove a Flag

Remove a flag when ALL of these are true:

  • Stable in production for 2+ weeks
  • Always enabled (no plan to disable)
  • Not user-configurable preference
  • Not tied to future feature (premium tier, etc.)

Implementation Templates

Step 1: Create the Flag

File: src/core/features.js

javascript
export const FEATURE_FLAGS = {
  // Existing flags...
  
  NEW_FEATURE: {
    phase: 'DISABLED',  // Start with DISABLED for new features
    description: 'Brief description of what the feature does'
  }
};

Description Guidelines:

  • Max 100 characters
  • Clear what/why, not how
  • Include user benefit if applicable

Step 2: Update Flag Usage

javascript
import { isFeatureEnabled } from '@/core/features.js';

// In components/views
if (isFeatureEnabled('NEW_FEATURE', 'home')) {
  // Show feature on home page
}

// In services
if (isFeatureEnabled('NEW_FEATURE')) {
  // Enable backend behavior
}

Context Parameters:

  • 'default' - General usage (most common)
  • 'settings' - Settings page only
  • 'home' - Home page specific
  • 'welcome' - Onboarding flow

Step 3: Add Tests

Test File: src/core/features.test.js

javascript
describe('NEW_FEATURE Flag', () => {
  it('should return false when DISABLED', () => {
    expect(isFeatureEnabled('NEW_FEATURE')).toBe(false);
  });
  
  it('should return true when ENABLED', () => {
    // Mock flag as ENABLED
    vi.stubGlobal('localStorage', {
      getItem: () => 'ENABLED'
    });
    
    expect(isFeatureEnabled('NEW_FEATURE')).toBe(true);
  });
  
  it('should respect SETTINGS_ONLY phase', () => {
    // Mock flag as SETTINGS_ONLY
    vi.stubGlobal('localStorage', {
      getItem: () => 'SETTINGS_ONLY'
    });
    
    expect(isFeatureEnabled('NEW_FEATURE', 'settings')).toBe(true);
    expect(isFeatureEnabled('NEW_FEATURE', 'home')).toBe(false);
  });
});

Step 4: Create Documentation

File: docs/learning/epic10_hygiene/FLAG_NEW_FEATURE.md

markdown
# NEW_FEATURE Feature Flag

**Status:** DISABLED
**Created:** YYYY-MM-DD
**Phase:** DISABLED → SETTINGS_ONLY → ENABLED → REMOVED
**Remove When:** Feature is stable for 2+ weeks

## Purpose
Brief description of why this flag exists.

## Success Metrics
- [ ] Feature works as intended
- [ ] No performance impact
- [ ] User feedback positive
- [ ] Telemetry shows usage

## Removal Plan
When this flag is removed:
- [ ] Remove isFeatureEnabled() checks
- [ ] Simplify conditional logic
- [ ] Update/remove related tests
- [ ] Archive this documentation

Step 5: Update Epic Documentation

File: docs/learning/epic10_hygiene/EPIC10_HYGIENE_PLAN.md

Add to "Future Flag Cleanup" table if applicable:

markdown
| Flag | Status | Remove When | Document |
|------|--------|-------------|----------|
| NEW_FEATURE | DISABLED | 2 weeks after ENABLED | FLAG_NEW_FEATURE.md |

Phase Updates

Moving from DISABLED to SETTINGS_ONLY

  1. Update flag phase:
javascript
NEW_FEATURE: {
  phase: 'SETTINGS_ONLY',  // Updated
  description: '...'
}
  1. Add Settings UI:
javascript
// In SettingsView.js
if (isFeatureEnabled('NEW_FEATURE', 'settings')) {
  // Add settings toggle for user testing
}
  1. Update tests for SETTINGS_ONLY behavior

  2. Update documentation with test plan

Moving from SETTINGS_ONLY to ENABLED

  1. Update flag phase:
javascript
NEW_FEATURE: {
  phase: 'ENABLED',  // Updated
  description: '...'
}
  1. Remove Settings-only guard (make available everywhere)

  2. Update tests for ENABLED behavior

  3. Update documentation with success metrics

Flag Removal Process (Hygiene Task)

Follow Epic 10 hygiene standards:

Pre-Removal Checklist

  • Flag has been ENABLED for 2+ weeks
  • No issues reported in telemetry
  • Feature is working as intended
  • No plan to disable this feature
  • Not a user preference setting

Step 1: Create Hygiene Branch

bash
# From main repo directory
git worktree add ../saberloop-hygiene hygiene/remove-new-feature-flag

cd ../saberloop-hygiene
npm install

Step 2: Remove Flag Code

  1. Remove from features.js:
javascript
export const FEATURE_FLAGS = {
  // Remove NEW_FEATURE entry
};
  1. Remove isFeatureEnabled() calls:
javascript
// Before
if (isFeatureEnabled('NEW_FEATURE')) {
  doSomething();
}

// After
doSomething(); // Always execute
  1. Simplify conditional logic:
javascript
// Before
if (isFeatureEnabled('NEW_FEATURE')) {
  return enhancedVersion();
} else {
  return basicVersion();
}

// After
return enhancedVersion(); // Always use enhanced

Step 3: Update Tests

  1. Remove flag-specific tests from features.test.js
  2. Update integration tests to expect new behavior
  3. Run full test suite to ensure no regressions

Step 4: Documentation Updates

  1. Archive flag documentation: Move to completed folder
  2. Update Epic 10 plan with removal date
  3. Create learning notes: docs/learning/epic10_hygiene/PHASE*_LEARNING_NOTES.md

Step 5: Quality Checks

Run complete hygiene checklist:

bash
npm test                    # Unit tests
npm run test:e2e            # E2E tests
npm run test:mutation        # Mutation testing
npm run arch:test           # Architecture validation
npm run typecheck           # TypeScript checking

Step 6: Commit and Merge

bash
git add -A
git commit -m "refactor(hygiene): remove NEW_FEATURE feature flag

- Remove isFeatureEnabled() checks for NEW_FEATURE
- Simplify conditional logic in [files]
- Remove flag from FEATURE_FLAGS object
- Update/remove related tests
- Archive flag documentation"

git push -u origin hygiene/remove-new-feature-flag

# Create PR after review
gh pr create --title "chore: remove NEW_FEATURE feature flag"

Step 7: Cleanup

bash
# From main repo
git worktree remove ../saberloop-hygiene
git branch -d hygiene/remove-new-feature-flag

Common Patterns

Gradual Rollout Pattern

javascript
// Phase 1: Settings only (user testing)
if (isFeatureEnabled('NEW_FEATURE', 'settings')) {
  showSettingsToggle();
}

// Phase 2: Limited exposure (telemetry gathering)
if (isFeatureEnabled('NEW_FEATURE', 'home')) {
  showFeatureOnHomePage();
}

// Phase 3: Full release
if (isFeatureEnabled('NEW_FEATURE')) {
  enableFeature();
}

Safe Removal Pattern

javascript
// Use feature flag as guard during development
const enhancedFlow = isFeatureEnabled('NEW_FEATURE') 
  ? newEnhancedImplementation() 
  : existingImplementation();

// After flag removal, the enhanced implementation becomes default
const enhancedFlow = newEnhancedImplementation();

Testing Guidelines

Unit Testing Requirements

Every flag needs these tests:

javascript
describe('FEATURE_NAME Flag', () => {
  it('should return false when DISABLED', () => {
    // Test default behavior
  });
  
  it('should return true when ENABLED', () => {
    // Test enabled behavior
  });
  
  it('should respect SETTINGS_ONLY phase', () => {
    // Test settings-only behavior
  });
  
  it('should handle test overrides', () => {
    // Test localStorage override capability
  });
});

Integration Testing

  • Test flag behavior in actual components
  • Verify Settings UI shows/hides correctly
  • Confirm feature works in each phase
  • Check telemetry tracks flag usage

E2E Testing

Add Playwright tests for critical flags:

javascript
test('feature flag settings toggle', async ({ page }) => {
  await page.goto('/settings');
  
  // Test settings-only flag visibility
  const toggle = page.locator('[data-testid="new-feature-toggle"]');
  await expect(toggle).toBeVisible();
  
  // Test toggle functionality
  await toggle.click();
  // Verify behavior changes
});

Troubleshooting

Flag Not Working

  1. Check import path: @/core/features.js
  2. Verify flag name matches FEATURE_FLAGS object
  3. Check context parameter if using SETTINGS_ONLY
  4. Test localStorage override for debugging

Test Override Not Working

javascript
// For debugging, force a flag state
localStorage.setItem('__test_feature_NEW_FEATURE', 'ENABLED');
// Then test isFeatureEnabled('NEW_FEATURE')

Removal Breaks Something

  1. Check for missed isFeatureEnabled() calls
  2. Verify conditional logic was properly simplified
  3. Run tests with --run flag (not watch mode)
  4. Check git diff for unintended changes

Quality Metrics

Track these metrics for flag management:

MetricTargetHow to Measure
Flag creation time< 30 minFrom skill start to tests passing
Flag removal time< 2 hoursFrom hygiene branch to merge
Test coverage100%All flag paths tested
Documentation completeness100%All fields filled in
Zero regressionsRequiredAll tests pass after removal

Related Files

  • src/core/features.js - Main flag definitions
  • src/core/features.test.js - Flag tests
  • docs/learning/epic10_hygiene/EPIC10_HYGIENE_PLAN.md - Epic tracking
  • Individual flag documentation files
  • Test files for components using flags

Integration with Other Skills

This skill integrates with:

  • epic-hygiene-process - For removal procedures
  • testing-suite-management - For test creation and validation
  • architecture-compliance - For validating flag usage patterns

Version: 1.0.0
Last Updated: 2026-01-15
Compatible with: Saberloop v2.0.0+