The Feature Flag Had No Owner

Sep 6

The flag began as a careful rollout control. Months later it still guarded two implementations, nobody remembered the intended default, and changing it required asking in several channels.

The flag had become production state without the ownership we would demand from a database table or API.

Why it stayed

Creation was part of delivery. Removal belonged to “later.” The ticket closed when exposure reached one hundred percent, not when the old path disappeared.

That left us paying for:

  • two behaviors to test;
  • two paths to secure;
  • ambiguous incident diagnosis;
  • configuration drift between environments;
  • a control whose blast radius was no longer understood.

The problem was not that flags are bad. The problem was treating their lifecycle as optional cleanup.

The resolution

We classified the flag before touching it: release flag, operational kill switch, experiment, or entitlement. Each type needed a different lifetime.

For the stale release flag, we inspected actual evaluation telemetry, confirmed that the old branch had no intended traffic, deleted the dead branch, and removed the flag definition in the same change sequence. We did not simply hide it from the dashboard.

New flags needed:

owner
purpose
created_at
expected_default
expiry_or_review_at
removal_issue
safe behavior when provider is unavailable

Operational kill switches could remain, but they needed drills and a conservative local default. Experiments needed exposure and analysis boundaries. Entitlements needed an authorization model rather than an informal boolean.

What I kept

Temporary infrastructure needs a removal path at creation time. An expiry date without an owner is only a future alert.

The mature question is not “Do we use feature flags?” It is “Which persistent decisions have we created, who owns them, and how does each one end?”


All Field Notes · Feature flags are production state · Architecture decisions need expiry dates

>