Let an AI agent create a feature flag, and validate it
You can let an AI coding agent create a feature flag when the flag is a file. The agent writes the Markdown file, adds the dif() call at the render site, and runs dif validate to check its own work. Because a flag is a file with a schema, the same CI gate that catches a human’s broken flag catches the agent’s.
Ask an agent to gate a feature against a hosted dashboard and it cannot. It has no login, so it writes if (flags.newThing) against a flag that was never created, or hand-rolls a boolean and calls it done. When the flag is a file in the repo, the agent creates it the way it creates any other file, and the validator holds it to the same standard as a human.
This post walks the whole loop: the flag file the agent writes, the call site it gates, and the dif validate pass that keeps a broken flag out of production.
Key Takeaways
- An AI agent creates a feature flag by writing a Markdown file in the repo, adding the
dif("flag-id")call at the render site, and shipping both in a pull request.dif validatechecks the agent’s work: weights total 100, the owner is a real email, referenced surfaces exist, and no call site points at a flag that is not defined.dif validateruns in CI, so a flag the agent breaks fails the build. Its work is gated exactly like a human’s.dif initwrites managed blocks intoCLAUDE.md,AGENTS.md, and.cursorrules, and installs skills, so the agent follows the repo’s flag format instead of guessing.- The agent can author and validate a flag. A human still owns the decision to ramp it and the hypothesis behind an experiment.
Why an agent can write a flag at all
A coding agent reads and edits the files in your repo. That is its whole interface. A feature flag in dif is a Markdown file in that repo, so it sits inside the agent’s reach the same way a component or a test does.
The agent does not have to infer the format. dif init writes a managed block into CLAUDE.md, AGENTS.md, and .cursorrules describing how flags work here, and dif installs agent skills for authoring and concluding experiments. This is the same repo-file convention that AGENTS.md established for project instructions and that Claude Code reads from CLAUDE.md. The agent reads the rules, then writes a flag that matches them.
The flag file the agent writes
Asked to gate the redesigned checkout, the agent drafts a flag file. It writes something like this, with the exact frontmatter documented in the format reference:
---
surface: checkout
owner: dana@example.com
status: active
variants:
off: 90
on: 10
metric: completed_checkout
---
The redesigned checkout, gated so we can ramp it on mobile first.
The frontmatter is the part the tooling reads: the surface it belongs to, the owner on the hook for it, the variants and their weights, and the metric a later experiment would move. The prose below is the rationale, which is why the flag exists at all when someone opens the file in two years.
Gating the code
A flag with no call site does nothing. The agent adds the check at the render site, using the flag id it just created:
if (dif("new-checkout") === "on") {
return <NewCheckout />;
}
return <Checkout />;
Both the flag file and this call site go into one pull request. A reviewer sees the flag and its use together, in the diff, instead of cross-referencing a dashboard against the code. That is the same reason feature flags for AI agents belong in the repo: the change is legible where the work happens.
dif validate checks the agent’s work
The safety net is the validator. dif validate runs in CI and checks the flag the agent wrote:
- The weights total 100. A flag whose variants sum to 90 fails.
- The owner is a real email, so no flag ships unowned.
- The surface and any targeted attributes exist, so a typo does not pass silently.
- Every
dif("...")call site points at a flag that is defined. An orphaned call fails. - Two active experiments on one surface must share an exclusion group or have disjoint audiences, or the validator raises
E007.
A broken flag looks like this in CI:
$ dif validate
✗ dif/checkout/new-checkout.md
weights total 90, expected 100
Because that check runs on the pull request, an agent that writes a malformed flag fails the build, the same as a human who fat-fingers a weight. The agent cannot quietly ship a flag that does not parse, target correctly, or add up. The CLI reference documents the full set of checks.
The agent follows the repo’s conventions
Left to guess, an agent invents a flag format per project. dif removes the guessing. The managed blocks tell it that flags live in dif/, that a flag is a file, and that dif validate has to pass. The installed skills give it the authoring and concluding steps as procedures, so it runs dif new to scaffold and dif validate to check, instead of hand-writing YAML and hoping.
The result is that an agent’s flag is indistinguishable from a careful human’s: correct frontmatter, a real owner, a call site that resolves, and a rationale in the prose. The agent skills guide covers driving this end to end.
Where an agent still needs a human
The validator checks structure, not judgment. It confirms the weights total 100. It cannot tell you whether 10% is the right ramp, whether completed_checkout is the metric that matters, or whether this experiment is worth running at all.
So the division is clean. An agent can create the flag, gate the code, and prove the flag is well-formed. A human still owns the call to ramp it, the hypothesis behind an experiment, and the decision to conclude. dif validate makes the agent’s work safe to merge. It does not make the experiment a good idea. That part is still yours.
FAQ
Can an AI coding agent create a feature flag? Yes, when the flag is a file in the repo. The agent writes the Markdown flag file, adds the dif("flag-id") call at the render site, and both go through review and CI like any other change. It cannot create a flag in a dashboard it has no way to open.
How does dif validate check a flag an agent wrote? It confirms the variant weights total 100, the owner is a valid email, and referenced surfaces and attributes exist. It scans the source for dif("...") call sites and fails on any that point at a flag that is not defined, and it raises E007 when two active experiments collide on one surface.
What stops an agent from shipping a broken flag? CI. dif validate runs on the pull request, so a flag with bad weights, an invalid owner, or an orphaned call site fails the build before it merges. The agent’s work is gated the same way a human’s is.
Can an agent run the whole experiment on its own? It can author the flag, gate the code, and validate the result. Deciding to ramp it, writing the hypothesis, and concluding the experiment stay with a human. The tooling checks that the flag is well-formed, not that the test is worth running.
Does this work with Claude Code and Cursor? Yes. dif init writes managed blocks into CLAUDE.md, AGENTS.md, and .cursorrules, the files those tools already read, so the agent knows the flag format without extra setup.
Getting started
Letting an AI agent create a feature flag is the ordinary consequence of flags being files. The agent writes the file, gates the code, and runs dif validate, and the broken ones fail the pull request. Install the CLI and scaffold a project:
npm install -g @dif.sh/cli
dif init
dif init writes the dif/ directory, the managed CLAUDE.md and AGENTS.md blocks, and the generated client. From there an agent can draft a flag with dif new, gate the render site, and check its own work in CI. The feature flags for AI agents post covers the wider workflow, and the CLI reference documents dif validate.