Do not merge an AI-written change straight to 100% of traffic. Bind it to a flag with a named owner, a rollout percentage that increases in steps, a kill path that does not require a redeploy, and an expiry date that forces someone to either finish the rollout or delete the flag. A flag with no expiry is not a safety mechanism; it is deferred cleanup.
Approval Is Not Release
An AI agent can produce a correct, reviewed, well-tested diff and still cause an incident, because "approved" and "live for everyone" are treated as the same moment. They are not. Approval judges the change. Release decides how much of your traffic meets it, and in what order.
This matters more for AI-written changes than hand-written ones, not because the code is worse, but because the volume is higher and the reviewer's mental model of the diff is thinner. A human author who wrote a change usually has a gut sense of what could go wrong. A reviewer approving an AI-written diff is judging a snapshot, not a change they lived through. Give that judgment a narrower blast radius by default.
Treating a feature flag as a temporary if-statement left over from testing, then merging it, deploying it, and forgetting it is still set to 100% "for now." A flag without an owner and an expiry date is a flag nobody will ever remove.
What a Flag Actually Buys You
A flag is worth the extra step only when it gives you something a plain deploy cannot: a way to change who sees a piece of code without shipping new code. Used well, it turns three separate risks into one small, reversible one.
| What you get | Why a redeploy alone can't do this | What it costs you |
|---|---|---|
| Gradual exposure (1% → 10% → 100%) | A deploy is binary; a percentage rollout needs runtime targeting. | Traffic must be split consistently per user or session. |
| Instant kill switch | A revert-and-redeploy takes minutes; a flag flip takes seconds. | The old code path must still exist and still work. |
| Isolating cause from a batch of changes | A single deploy often bundles several AI-written diffs together. | Each risky change needs its own flag, not one flag for the release. |
| Testing in production for one account or cohort | Staging rarely reproduces real data shape or load. | Targeting rules must be trustworthy, not just percentage-based. |
If none of those four apply, a flag adds overhead without adding safety. A same-day typo fix does not need a rollout plan. Reserve flags for changes where the blast radius, the confidence level, or the need for a fast undo is genuinely uncertain — which is most AI-written behavior changes, and few AI-written one-line fixes.
The Five Parts of a Flag Spec
Write the flag's spec before the agent starts, the same way you would write an approval packet. A flag with no spec drifts into permanent, undocumented branching logic.
Name the flag after the change, not the team or the ticket: checkout-retry-backoff, not growth-experiment-14. State exactly which code path it guards and which it does not.
Pick concrete steps, not a vague "gradually increase": internal accounts, 1%, 10%, 50%, 100%, with a minimum soak time at each step before moving on.
Name the specific signal that triggers an immediate flip back to off — an error rate threshold, a latency budget, or a failed invariant check — and who is allowed to pull it without further approval.
Track the metric that matters separately for the flag-on and flag-off populations. Without that split, you cannot tell whether a spike is the change or unrelated noise.
Every flag gets a date it must be fully on, fully off, or deleted, and one named person accountable for that outcome. No exceptions for flags that "might be useful later."
Flag Hygiene: The Debt Nobody Budgets For
Every flag your AI assistant leaves behind is a permanent branch in your code until someone removes it. That is cheap in isolation and expensive in aggregate: a codebase with forty stale flags has forty untested combinations of on/off state, and nobody remembers which ones are still load-bearing.
Because an AI agent can generate flag-gated code faster than a team can review and retire it, flag creation needs a matching flag-deletion habit, or the count only grows. Treat "add the flag" and "schedule its removal" as one unit of work, not two.
A flag stays in one of three states: rolling out, fully shipped and awaiting cleanup, or fully reverted and awaiting cleanup. "Permanently half-on for some segment" is not a fourth state — it is a targeting rule, and it belongs in configuration, not in a flag meant to gate a rollout.
A Copy-Paste Flag Spec
Keep this next to the pull request that introduces the flag, so the rollout plan travels with the code instead of living only in someone's memory.
## Feature Flag Spec
Flag name: <describes the change, not the team or ticket>
Guards: <exact code path or behavior>
Owner: <one named person>
Rollout steps: <e.g. internal → 1% → 10% → 50% → 100%>
Minimum soak time per step: <duration>
Kill condition: <specific metric, threshold, or check>
Who can flip it off: <role, no extra approval required>
Telemetry (flag-on vs flag-off):
- [ ] Primary success metric tracked per side
- [ ] Error/latency signal tracked per side
- [ ] Dashboard or query link: <url>
Expiry: <date the flag must be fully on, fully off, or deleted>
Cleanup ticket: <link, filed at creation time, not after>
The expiry and cleanup ticket are not optional fields. A flag spec without them describes a rollout with no planned end.
Rolling Back Without a Redeploy
A flag flip is not the same guarantee as a code revert, and treating it that way is a common failure mode. Flipping a flag off stops new traffic from hitting the new path; it does not undo writes the new path already made, notifications it already sent, or state a downstream service already changed based on it.
- Flip first for anything read-heavy or stateless. A flag is close to a full undo for rendering, ranking, or read-path logic.
- Treat writes separately. If the flagged path writes data, plan the data-side recovery independently of the flag — the flag stops new damage, it does not repair existing damage.
- Don't let the flag hide a needed revert. If the kill condition fires because the code itself is broken, flip the flag off immediately, but still ship the fix or revert; a flag left off indefinitely just means the bug is dormant, not gone.
- Verify the old path still works. A flag only rescues you if the code it falls back to has kept running correctly the whole time it was flagged off.
A flag that has been at 100% for months quietly rots on the "off" side: dependencies change, schemas shift, and the fallback path may no longer run at all. Before you rely on a kill switch in an incident, know when it was last actually exercised.
When Not to Use a Flag
Some AI-written changes should not be gradually rolled out at all. A security fix needs to ship to everyone immediately, not soak at 10% while the vulnerable path stays open for the rest. A destructive data migration is not undone by flipping a flag, so the safety has to come from the migration plan itself, not from wrapping it in a toggle that implies a fast way back.
Reserve flags for changes where gradual exposure and a fast kill path genuinely reduce risk. For everything else, put the safety budget where it belongs: a tighter change scope, a real approval gate, and a tested rollback plan.
Use AI Agent Rollback Plans to decide what an agent may do before it acts, and The AI Change Budget to bound how much it changes at once. This plan picks up after both: once a change is approved and scoped, a flag decides how it actually reaches your users.