Development & Code · master area
Feature Flag Implementation
Wrapping new behaviour so rollback is one switch — and so trunk can carry unfinished work without exposing it. Both flag-on and flag-off paths are tested; the flag's removal date is named at creation.
Owners: Developer Phase it lives in: How We Build (Volume IV) The corpus principle this enacts: Rollback possible is not. A confirmed time is.
Where it lives in the chain
- How We Build · Feature Flags — the canon: when and when not, the lifecycle
- How We Build · Gradual rollout and flag setup — how flags carry the rollout
How to do this
- Convention — every flag has: a name (
grading.shortcut-submit), a default (false), an owner, and a removal date at creation. - Convention — both paths (flag on, flag off) are tested. If the flag-off path goes untested, the rollback is theatre.
- Related craft — Flag Lifecycle — birth → cleanup
What good implementation looks like
if (flags.enabled('grading.shortcut-submit', { user })) {
return submitWithShortcut(exam)
}
return submitClassic(exam)The two paths are clearly named. The flag-off path stays maintained until the flag is removed. The PR that adds the flag also adds the removal task to the backlog with a date. A flag created without a removal date is technical debt born already due.
The discipline: flags carry the rollout for days or weeks, not months. A flag still wrapping behaviour six months after launch is no longer a flag — it is a permanent branch in the code with a switch nobody flips. The PR that removes the flag is as important as the PR that added it.
Related crafts
- Feature Flag Platform — the runtime
- Flag Lifecycle — the discipline of removal
- Trunk-Based Development — flags are how trunk-based handles unfinished work