When your agent adds a config flag, it's avoiding a product decision
Agents default to 'make it configurable' because training data rewards flexibility. Every flag they add is a branch nobody tests and a decision nobody made. The cheap counter-move is to force a default first.
You open the PR and the diff has it: a new config file with three flags, a settings struct, and a --enable-x CLI argument. The agent did the thing you asked. It also did not decide anything.
This is the most consistent pattern I see from AI coding assistants on medium-sized features. Ask for a retry-with-backoff flow, and you get RETRY_MAX_ATTEMPTS, RETRY_BACKOFF_MS, and RETRY_JITTER_FACTOR. Ask for a rate limiter, and you get RATE_LIMIT_RPM, RATE_LIMIT_BURST, and RATE_LIMIT_STRATEGY. The code is clean, the naming is consistent, the tests cover the happy path. None of it is a decision.
Why agents default to flags
The training data favors flexible code. Clean architecture books, framework source code, and senior engineer PRs all model flexibility as a virtue. When the agent is uncertain about your product constraints — and it almost always is — the safe move is to expose the uncertainty as a knob rather than make a call. It can't lose an argument by guessing a wrong default if it never guesses.
Humans do this too. The difference is that a human senior engineer will flag it in review: "Why is this configurable? Just pick 3 retries." An agent reviewing its own code doesn't push back, because the next-token distribution doesn't include the move disagree with the previous sentence written by myself.
The cost isn't the flag itself
A single config key is harmless. The cost compounds in three places:
Every flag is a branch nobody tests. Three flags mean 2^3 = 8 combinations if you're being naive, and in practice the agent writes one test for the default combination. The other seven exist only in production. When RETRY_JITTER_FACTOR=0 interacts with RETRY_BACKOFF_MS=0 you get a tight loop, and nobody saw it coming because the default path never hit it.
Every flag pushes a decision to runtime. A config file is where product questions go to die. "Should we retry on 429 or 503?" becomes a flag, and then on-call has to have the argument at 2am instead of the engineer who wrote the code having it on Monday. The decision didn't disappear. It moved to a worse venue.
The flag graph becomes a second language nobody reads. After six months you have 40 config keys, half of which were never changed from their default, and onboarding a new engineer requires walking through a matrix that was supposed to reduce cognitive load. This is the classic internal-platform failure, and agents are accelerating it.
The three-question filter
I started doing this in review, and it catches almost every premature flag:
- What breaks if we hardcode the value and ship? If the answer is "nothing for the next two quarters," hardcode it. YAGNI applies to agent output too.
- Name one customer or deployment where the default would be wrong. If you can't, you don't need a flag. You need a comment explaining the choice.
- Is this a tenant-level choice or a runtime behavior? Tenant-level (per-workspace, per-plan) is a real config surface. Runtime behavior (backoff, retries, timeouts) is usually an engineering default that should be tuned in code, not in a YAML file that nobody reads at 2am.
When an agent proposes a flag, I paste these three questions back and ask it to answer before writing the struct. About half the time it comes back with "you're right, hardcode 3 retries with exponential backoff," and the PR gets smaller. The other half, it identifies a genuine cross-deployment difference — and then we have a real reason for the flag, with a comment explaining why.
The exception
Config flags are the right answer when the feature genuinely has two incompatible behaviors that different production environments need. Multi-region write routing, feature flags for staged rollout, and per-tenant quota limits are real. The test is the same: if you can't name the deployment that needs the non-default value on day one, the flag is theater.
The pattern isn't "never add config." It's "make the agent justify the flag before it writes the struct." Left to its own defaults, it will ship you a flexible system that has decided nothing — and you'll discover that at 3am when the flag you never thought about needs a value.

