Two Ways to Isolate Incomplete Features
Feature flags: incomplete code is merged to main behind a runtime toggle. if (flags.enableNewSettings) { return <NewSettingsPage />; } else { return <OldSettingsPage />; }. The new settings code: is in production, deployed, and running — but invisible to users until the flag is enabled. Toggle the flag: the feature appears instantly (no deployment needed). The code is: always in main, always tested in CI, and always deployable. Merge conflicts: zero (the code is in main, not isolated in a branch).
Long-lived branches: incomplete code lives in a feature branch (feature/new-settings) until the feature is complete. The branch: is separate from main, may run for days or weeks, and accumulates: merge conflicts (main changes while the branch is alive), CI drift (the branch may not be tested against the latest main), and review burden (a 2-week branch produces a massive PR). When complete: the branch is merged to main (potentially with painful merge conflict resolution).
Without an isolation rule: the AI creates a feature branch for every task (even small ones that should merge directly) or generates code without feature flags (missing the trunk-based team convention). The rule tells the AI: which isolation mechanism the team uses and when to apply it. The choice is: team-determined and should be explicit in CLAUDE.md.
Feature Flag Rules for AI
Feature flag AI rule: "For features that take more than 1 day: wrap in a feature flag. Flag implementation: const flags = useFeatureFlags(); if (flags.newSettings) { ... } else { ... }. Flag source: environment variable (FEATURE_NEW_SETTINGS=true) or feature flag service (LaunchDarkly, Flagsmith, Vercel Edge Config). Flag naming: FEATURE_DESCRIPTION (FEATURE_NEW_SETTINGS, FEATURE_CURSOR_PAGINATION, FEATURE_DARK_MODE). Merge flag-wrapped code to main immediately — the flag keeps it hidden."
Flag-wrapped code generation: the AI should generate code that: works with the flag ON (new feature) AND with the flag OFF (old behavior). Both paths: must be tested. The flag: is a conditional that selects between old and new code paths. AI rule: 'When generating flag-wrapped code: ensure both flag-on and flag-off paths work correctly. Test both paths. The flag-off path: is the current production behavior (must not break). The flag-on path: is the new feature (must work when enabled).'
The flag rule prevents: the AI removing old code when adding new feature code (the old code must remain as the flag-off path), generating code that only works with the flag on (the flag-off path is broken — production users see the broken path), or creating a feature branch instead of a flag (when the team convention is: flags for isolation, not branches). The flag is: a temporary runtime switch, not a permanent code pattern.
- Flag for: features taking > 1 day. Merge to main immediately behind the flag
- Both paths work: flag-on (new feature) AND flag-off (old behavior, current production)
- Test both: CI tests run with flag-on AND flag-off to verify both code paths
- Flag naming: FEATURE_DESCRIPTION (env var) or camelCase (feature flag service)
- AI generates: flag-wrapped code with both paths, not code that removes the old behavior
AI generating flag-wrapped code: the flag-on path (new feature) AND the flag-off path (old behavior) must both work correctly. The flag-off path IS production behavior. Breaking it = breaking production for all users. Test both paths in CI. The flag is temporary; both paths must be solid.
When Branches Are Appropriate
Branches are appropriate for: short-lived work (hours to 1-2 days — a bug fix, a small feature, a refactor), PRs that merge quickly (the branch lives for the duration of the code review, then is deleted), and experimental work that may be discarded (a prototype branch that explores an approach — delete if the approach does not work, merge if it does). Short-lived branches: do not accumulate merge conflicts, do not drift from main, and produce small reviewable PRs.
Branches are problematic for: long-lived features (2+ weeks of development on a separate branch). Problems: merge conflicts accumulate (main changes while the branch is alive — resolving conflicts wastes time and introduces bugs), CI drift (the branch was green when created but main has changed — the branch may no longer be compatible), large PRs (2 weeks of work = a massive PR that reviewers skim instead of reviewing thoroughly), and delayed integration (other teams cannot use or test the feature until the branch merges).
AI branch rule: "Create short-lived branches for: bug fixes, small features (under 2 days), and refactors. Name: descriptive-kebab-case (fix-login-redirect, add-password-validation). Merge quickly via PR. Delete after merge. For features taking more than 2 days: use a feature flag instead of a long-lived branch. Never keep a branch alive for more than 1 week — if the feature is not done, merge the progress behind a flag and continue on a new branch from main."
- Short-lived (hours to 2 days): bug fixes, small features, refactors. Merge quickly via PR
- Long-lived (2+ weeks): merge conflicts, CI drift, large PRs, delayed integration. Avoid
- Over 2 days: use a feature flag instead. Merge daily to main behind the flag
- Over 1 week: if still in a branch, merge progress behind a flag and start fresh from main
- AI rule: short branches for small work, flags for large features. No long-lived branches
Feature Flag Cleanup Lifecycle
Flags must be removed after the feature is fully launched. The flag lifecycle: (1) Create: add the flag when starting the feature (flag-off by default). (2) Develop: merge code behind the flag to main. Both paths tested. (3) Enable: turn on the flag for a percentage of users (canary rollout). (4) Fully enable: 100% of users see the new feature. (5) Remove: delete the flag check, remove the old code path, remove the flag from the configuration. Step 5 is: the most often skipped and the most important.
Flag cleanup AI rule: "After a feature is fully launched (flag enabled for 100% for 2+ weeks with no issues): remove the flag. Remove: the if/else check, the old code path (flag-off), and the flag from the feature flag service. Flag cleanup: should be a task tracked in the project management tool. Unremoved flags: accumulate as dead code, confuse future developers (is this flag still active?), and slow down the AI (more conditional paths to understand)."
The cleanup rule matters for AI because: a codebase with 50 unremoved feature flags has: 50 conditional branches that the AI must understand (which path is active? which is dead?). The AI may: generate code that interacts with a flag-off path that is dead code (nobody takes the else branch anymore). Clean flags: reduce codebase complexity for both humans and AI. The rule ensures: flags are temporary, not permanent conditional clutter.
- Lifecycle: create → develop behind flag → canary enable → full enable → remove flag + old code
- Remove after: 2+ weeks at 100% with no issues. Delete flag check + old code + config entry
- Most often skipped: flag removal. 50 unremoved flags = dead code + AI confusion
- Track cleanup: as a project management task (Jira ticket, GitHub issue) after full launch
- Clean flags: reduce complexity for humans AND AI (fewer conditional branches to understand)
Each unremoved flag: adds a conditional branch that the AI must understand (is this active? dead?). 50 flags: the AI may generate code interacting with a flag-off path that nobody takes anymore. Cleanup rule: remove the flag + old code within 2 weeks of full launch. Track cleanup as a project task.
When to Use Each: Decision Framework
Use feature flags when: the feature takes more than 2 days (merge daily behind a flag), the feature affects: shared code that other developers depend on (a flag lets others see the changes without waiting for the branch to merge), the team practices: trunk-based development (flags are the trunk-based isolation mechanism), or a gradual rollout is needed (enable for 5% of users, then 25%, then 100%). Flags are: the modern isolation mechanism for web applications.
Use branches when: the work is small and quick (under 2 days — a branch merges before conflicts accumulate), the work is: experimental (may be discarded — deleting a branch is easier than removing a flag), the change is: a refactor that does not need gradual rollout (rename a module, restructure files — it works or it does not), or the team uses: GitFlow with feature branches (the branching model requires feature branches). Branches are: the appropriate mechanism for short, contained work.
The AI rule combines both: "Short work (under 2 days): branch from main, PR to main, merge and delete. Long work (over 2 days): merge to main daily behind a feature flag. Flag cleanup: remove within 2 weeks of full launch. Never: keep a branch alive more than 1 week. Never: leave a flag in the code more than 2 weeks after full launch." Two isolation mechanisms, each for the right duration.
Under 2 days: branch from main, PR, merge, delete. Quick, no accumulation. Over 2 days: merge daily behind a feature flag. Zero merge conflicts, code always in main, gradual rollout when ready. Over 1 week in a branch: merge progress behind a flag and start fresh. Two mechanisms, each for the right duration.
Isolation Mechanism Summary
Summary of feature flags vs branches AI rules.
- Flags: runtime toggle, code in main behind conditional, merge daily, gradual rollout possible
- Branches: git isolation, code separate from main, merge once when complete, all-or-nothing
- Flags for: features > 2 days, gradual rollout, trunk-based teams, shared code changes
- Branches for: features < 2 days, experimental work, refactors, GitFlow teams
- Flag-wrapped code: both paths (on + off) must work and be tested
- Flag cleanup: remove within 2 weeks of full launch. 50 unremoved = dead code + AI confusion
- Branch limit: never alive > 1 week. Merge progress behind flag and start fresh if needed
- Combined rule: short work = branch. Long work = flag. Cleanup both: delete branch, remove flag