The AGENTS.md block your coding agent needs to work with feature flags
AGENTS.md feature flags start with one paragraph in the file your coding agent reads on session start. That paragraph tells the agent where flag files live, what shape they take, how to gate code with one, and how to validate before opening a PR. Without it, the agent guesses, and the guesses do not match your repo. The block is one file with five things in it.
AGENTS.md is now an open specification. As of December 2025 it is adopted by 60,000+ open-source projects and 20+ AI coding tools, and hosted by the Linux Foundation Agentic AI Foundation. Codex, Cursor, and most agentic coding tools read it first. Claude Code still reads CLAUDE.md by default, with @AGENTS.md on the first line as the settled bridge. This post shows the block, a coding-agent transcript with and without it, and how feature flags for AI agents work once it is in place.
Key Takeaways
- AGENTS.md is an open specification adopted by 60,000+ open-source projects and 20+ AI coding tools by December 2025. Codex and Cursor read it; Claude Code still reads
CLAUDE.mdby default.- A coding-agent-ready feature-flag block contains five things: file location, frontmatter schema, gating pattern, naming rule, and the local validation command (
dif validate).- Without the block, coding agents invent flag patterns that do not match the repo. With it, they write the correct file on the first turn.
dif initwrites managed blocks intoAGENTS.md,CLAUDE.md, and.cursorrules;dif buildrefreshes them alongsidecontext.json.- The block only helps if the agent reads it. Some IDE integrations bypass repo instruction files. Check yours before you rely on it.
What AGENTS.md, CLAUDE.md, and .cursorrules actually do
Each is a Markdown file at the repo root that tells a coding agent how this codebase works. The agent reads it on session start, before it edits anything. Different tools favor different filenames.
AGENTS.md was formalized as an open spec in August 2025 by OpenAI, Google, Cursor, and Factory, and donated to the Linux Foundation Agentic AI Foundation in December 2025. Codex, Cursor, Aider, and most other agentic coding tools read it. CLAUDE.md predates the spec; Claude Code still reads it first, and the settled workaround is to put @AGENTS.md on the top line of CLAUDE.md so the shared block is imported. .cursorrules is Cursor’s legacy format, still read alongside AGENTS.md. The spec also supports per-package files with closest-file-wins resolution, so a monorepo can hold different flag conventions in per-package AGENTS.md files.
| Coding tool | Reads first | Fallback |
|---|---|---|
| Codex | AGENTS.md | None (co-authored the spec) |
| Cursor | AGENTS.md | .cursorrules (both read; AGENTS.md wins) |
| Claude Code | CLAUDE.md | @AGENTS.md import (August 2026 default) |
| Aider | AGENTS.md | CONVENTIONS.md |
What a coding-agent-ready feature-flag block contains
Feature flags are one of the highest-payoff conventions to document. Guessing produces flags with the wrong shape, wrong location, wrong naming, and no validation. Any of those means the PR bounces in review or the SDK breaks at runtime.
A coding-agent-ready feature-flag block covers five things:
- Where flag files live. The exact directory (
dif/experiments/active/), the filename shape (<id>.md), and where concluded files move. - The frontmatter schema. Real fields with real types: owner email, surface, variants with weights that sum to 100, audience, exclusion group.
- The gating pattern. The exact SDK call at the render site (
dif("flag-id")), the import path, and where it goes. - The naming rule. Kebab-case, surface-prefixed, whatever the team uses. An agent invents a rule if you do not name one.
- How to validate before the PR. The command (
dif validate), and what a green pass and a red failure look like.
Every one of these lands in the file the agent reads at session start.
A real AGENTS.md feature-flag block
Here is the block dif emits into AGENTS.md, CLAUDE.md, and .cursorrules on dif init, delimited by managed comments so dif build can refresh it without touching the rest of your file:
<!-- dif:start -->
<!-- generated by dif v0.6.0; safe to re-run `dif init` to refresh -->
# Working with dif.sh in this repo
This project uses dif.sh. Feature flags and experiments live as `.md` files
under `dif/experiments/`, and the dif CLI compiles them into a typed
TypeScript client (`dif/generated/client.ts`) the app imports at render time.
## File layout
dif/experiments/active/<id>.md drafts and running flags
dif/experiments/concluded/<id>.md archived by `dif conclude`
dif/surfaces/<surface>.md one per surface, learnings log
dif/audiences/<attr>.ts one resolver per audience attr
dif/config.yaml audience attrs, bucketing, events
dif/context.json agent-facing summary of active flags
## The verbs
- `dif new <id> --surface <name>`: draft a flag file
- `dif validate`: schema, weight, audience, exclusion checks (exit 1 on error)
- `dif build`: compile the typed client, refresh `context.json`
- `dif conclude <id> --decision "<text>"`: archive and log the outcome
## The naming rule
Flag IDs are kebab-case and surface-prefixed. `checkout-cta-copy`, not
`checkoutCTA` or `new_flow_v2`.
## Before opening a PR
Run `dif validate`. A broken flag fails the PR the way a broken build does.
<!-- dif:end -->
The lines a team customizes are the naming rule and the file paths if dif init was run with a non-default directory. Everything else stays identical across repos, and dif build keeps it in sync with the current CLI.
What the coding agent does without the block, and with it
Same repo, same task (“add a feature flag to gate the new checkout CTA”), same coding agent. The only difference is whether the block is committed.
Without the block. The agent sees no repo convention and improvises:
user: add a feature flag to gate the new checkout CTA
agent: I'll add a feature flag. Creating a config file.
Created: config/features.json
{ "new_checkout_cta": { "enabled": true, "rollout": 100 } }
Updated: src/lib/components/OrderSummary.svelte
+ {#if features.new_checkout_cta.enabled}
+ <button id="checkout-cta">Complete order</button>
+ {:else}
+ <button id="checkout-cta">Checkout</button>
+ {/if}
Flag added. Ready to commit.
Wrong location (config/features.json instead of dif/experiments/active/), wrong file format (JSON, not the .md schema), wrong naming (new_checkout_cta in snake_case, no surface prefix), no validation. The PR bounces in review or the SDK errors at runtime.
With the block. The agent reads AGENTS.md first and writes the right file:
user: add a feature flag to gate the new checkout CTA
agent: Reading AGENTS.md. This repo uses dif. Flags are .md files under
dif/experiments/active/, gated with dif("flag-id"), validated with
`dif validate` before PR.
Created: dif/experiments/active/checkout-cta-copy.md
---
id: checkout-cta-copy
owner: chris@niftic.agency
surface: checkout
variants:
- { name: control, weight: 50 }
- { name: benefit_led, weight: 50 }
---
Updated: src/lib/components/OrderSummary.svelte
+ import { dif } from '$lib/dif/generated/client';
<button id="checkout-cta">
+ {dif('checkout-cta-copy') === 'benefit_led' ? 'Complete order' : 'Checkout'}
</button>
$ dif validate
✓ 1 experiment, 0 errors
Flag added and validated. Opening PR.
Right directory, right frontmatter, right gating pattern, right naming, ran the validator. The agent got the boring parts correct on the first turn because it read them off the block. The PR review is now about the hypothesis and the copy, not whether the file is in the right folder. See ai agent create feature flag for the full workflow this enables.
How dif generates the AGENTS.md feature-flag block for you
dif init writes the block into AGENTS.md, CLAUDE.md, and .cursorrules in one pass. If a file exists, dif appends the managed section between <!-- dif:start --> and <!-- dif:end --> markers instead of overwriting your content. If a file does not exist, dif creates it.
$ npm install -g @dif.sh/cli
$ dif init
✓ dif/config.yaml
✓ dif/surfaces/checkout.md
✓ dif/experiments/active/example.md
✓ AGENTS.md (appended dif block)
✓ CLAUDE.md (created with dif block)
✓ .cursorrules (created with dif block)
Every dif build after that refreshes the block. If dif ships a new verb, validation code, or config field, dif build updates the file the agent reads without you touching it. The same dif build emits context.json, so the block explains how flags work and context.json carries the current flag state alongside it. dif also installs agent skills that let an agent author and conclude experiments once it knows the rules.
For a monorepo, run dif init in each package. The AGENTS.md spec’s closest-file-wins rule means an agent editing packages/checkout/ reads that package’s AGENTS.md, not the root one. Three packages, three flag conventions, three blocks that dif build keeps in sync.
The tradeoff
The block is a contract with the coding agent, not a guarantee. It only helps if the agent reads it.
Codex, Cursor, Aider, and Claude Code all read repo instruction files by default. Some IDE-embedded assistants (older Copilot integrations, vendor-locked in-editor bots) do not. For those, the block is invisible and the agent falls back to guessing.
Check which files your coding agent reads before you rely on the block. The agents.md spec homepage lists current adopters.
FAQ
Should feature flags go in AGENTS.md or CLAUDE.md? Both. The same managed block goes in both files (and in .cursorrules) so any coding agent your team uses reads the same rules. dif init writes all three at once so they never drift.
Does Claude Code read AGENTS.md? Not by default, as of August 2026. Claude Code reads CLAUDE.md first. The settled workaround is @AGENTS.md on the first line of CLAUDE.md, which imports the shared block.
What is the difference between AGENTS.md and .cursorrules? AGENTS.md is the open spec (August 2025) backed by OpenAI, Google, Cursor, and Factory, and hosted by the Linux Foundation. .cursorrules is Cursor’s original format from before the spec. Cursor still reads both; new projects should write AGENTS.md.
How does dif keep the AGENTS.md block in sync? dif build regenerates the block whenever you run it, alongside the typed client and context.json. The managed section between <!-- dif:start --> and <!-- dif:end --> gets rewritten; your own content outside those markers is left alone.
Can I use AGENTS.md for feature flags without dif? Yes. The block is Markdown. Copy the template above, replace the file paths and naming rule with your project’s conventions, and commit it. You lose the auto-refresh and the dif validate line, but the agent still reads the block.
Getting started
The block is one file, five things: file location, frontmatter schema, gating pattern, naming rule, validation command. Without it, a coding agent invents a pattern that does not match your code. With it, the agent writes the right file, runs dif validate, and opens the PR. AGENTS.md feature flags are the contract that makes agent-authored flag work a review problem instead of a rewrite problem.
dif writes and maintains the block for you. Install the CLI:
npm install -g @dif.sh/cli
dif init
The block lands in AGENTS.md, CLAUDE.md, and .cursorrules, and dif build keeps it current. The dif docs cover the full CLI reference.