Feature flags for AI coding agents: the off switch nobody remembers to flip
The agent's diff was eight lines: a new pricing table, wrapped
entirely in if (Flag::active('new_pricing_table', $user)). Existing
users hit the old code path exactly as before. The reviewer approved
it in under a minute, because nothing about the visible product had
actually changed yet. That's the whole appeal of a feature flag for
an AI coding agent: ship the code today, decide later whether anyone
sees it.
Fast-forward four months. Grep the codebase for that flag name and it's still there, still checked, still gated, sitting at a hundred percent rollout for so long that "gated" stopped meaning anything. The agent that wrote it is long gone. The engineer who approved the PR doesn't remember approving it. The flag did exactly the job it was built for. Nobody ever did the second job: deciding when the flag's job was finished.
Why a feature flag feels safe when an AI coding agent ships it
A feature flag splits one hard question, "is this safe to ship," into two easier ones: "is this safe to merge" and "is this safe to turn on." An AI coding agent only ever has to answer the first one. The code merges to main, the flag defaults to off, the test suite passes, and nothing in production changes until a human, or another agent, flips the switch later. It's cheap to add, safe by default, and it lets an agent keep shipping instead of blocking on a decision that was never its to make.
Pete Hodgson's canonical writeup on feature toggles names several kinds worth knowing, release toggles, ops toggles, experiment toggles, permission toggles. An agent can use any of them correctly and still leave you holding a problem the flag itself never solves.
A flag is supposed to be the safe, reversible cousin of a database migration: it runs once against real data and mostly can't be undone. Flip a flag back and the old behavior returns instantly, no rollback script needed, but only if someone still remembers the flag is there to flip.
The half of the job an AI coding agent never gets assigned
Shipping a flag is a task with a clear definition of done: the code merges, the flag defaults off, the tests pass. Retiring a flag isn't a task at all, it's a decision nobody scheduled. Somebody has to notice the rollout finished, confirm nothing still depends on the old path, delete both branches of the conditional, and ship that as its own reviewed change.
Hodgson's article names the pattern exactly: "Feature Flags have a tendency to multiply rapidly, particularly when first introduced. They are useful and cheap to create and so often a lot are created." He recommends treating every flag as inventory with a carrying cost. An agent that only ever does the cheap half of that trade, adding flags and never subtracting them, optimizes for the wrong side of the ledger without ever seeing the pile it's building.
Paying down the resulting debt later looks identical to paying down any other kind: someone has to read code nobody has touched in months and prove it's safe to delete. A stale flag is worse than ordinary dead code, though, because it isn't dead. It's still checked, on every request, by code that still runs both ways.
What happens when two AI coding agents share one flag
Run more than one agent at a time and a flag stops being one decision, it becomes shared state two sessions can quietly disagree about. Worktrees solve the git half of parallel agents: separate branches, separate directories, nothing collides. A flag lives in application state neither worktree isolates, so two agents can merge cleanly and still contradict each other once their code runs.
One session wraps a pricing controller in a flag check. A second, working the same week on a nightly job that recalculates prices, never sees the flag in its own task and never adds the check. The flag reads off in the browser and on in the batch job, caught only when someone reconciles the numbers. The inverse mistake shows up during cleanup: an agent deletes what looks like dead code, never realizing a flag elsewhere is the only thing standing between it and live traffic. Flipping a flag to a hundred percent deserves the same permission and undo thinking you'd want before any agent runs something else you can't easily reverse.
Where feature flags go wrong, and what they really cost
A dormant flag is not dead code, it's a loaded switch. In 2012, a Knight Capital deployment left a dormant, years-old trading feature called Power Peg live on one server out of eight because a technician missed it during rollout. The new release reused that flag bit: on the seven updated servers it meant the new feature, on the one unpatched server it meant the old one, and the old one started trading. The firm lost roughly $440 million in forty-five minutes, not because anyone wrote bad code that day, but because old code behind an old flag was never removed, only quieted.
A flag flipped the wrong way ships to everyone, not no one. GrowthBook's engineering team has named this exact failure mode in agents that manage flags directly: one can ship a flag enabled by default instead of disabled, the precise inversion of what it exists to prevent. In their words, "you only find out later what it skipped or got wrong."
Nobody owns the removal, so nobody does it. A flag with no name attached to "decide when this comes out" outlives everyone who understood why it went in.
Give every flag an owner before you give it a name
SanuDesk is a desktop app built around exactly that gap between shipping a flag and retiring one. Your Claude Code, Codex and Gemini sessions tile into one grid, so when one session's diff wraps a change in a new flag, that's something you see forming, not something you reconstruct from a grep six months later. Work arrives through a Kanban board: "ship the pricing table behind a flag" is a card, and finishing it can spawn the follow-up card, "remove the pricing table flag," parked in a lane where it stays visible instead of living only in someone's memory. A recurring sweep, grep the codebase for every flag conditional and check its age against git blame, becomes a Loop, journaled per run instead of a cleanup everyone agrees matters and nobody schedules. Because SanuDesk is bring-your-own-model, that audit can run on a cheap model on a timer while the expensive one keeps shipping. The grid and board are in the free plan (see pricing).
Count your flags before your agents add the next one
Grep your codebase right now for however your team checks flags,
Flag::active, if (flags., whatever the local convention is. For
every match, run git blame on that line and note the date. Anything
older than ninety days has outlived a normal rollout window: it's
either fully live and safe to delete, or nobody actually knows, which
is the more expensive answer to find out this way.
If the list is short, you're in good shape. If it isn't, you've just found the backlog nobody put on the backlog.
Download SanuDesk free to see every flag a session adds before it piles up, or check how the grid, the board and Loops fit together on the features page.