Every flag is a small debt. Used well it buys you the ability to ship continuously and turn things off at 2am. Used badly you end up with a codebase where no two users run the same logic.
Give every flag an expiry
A flag needs an owner and a removal date written down when it is created. If nobody can say when it goes away, it is not a flag - it is configuration you have not admitted to yet.
Two kinds, kept separate
- Release flags: temporary, hide unfinished work, deleted after rollout
- Operational flags: permanent kill switches for things that can fail
Never nest them
Two flags means four states to test. Three means eight. We cap combinations by keeping flags independent and short-lived.
Clean-up is a ticket, not a hope
We schedule the removal ticket at the same time we add the flag. Otherwise it never happens, and six months later somebody is afraid to delete a branch nobody has run in a year.