← Blog

What is context.json? The flag state your agent reads

context.json is the file dif generates so a coding agent can read your live feature-flag state. dif build writes it, and an agent like Claude Code or Cursor reads it on session start. One file lists every active flag and each surface’s latest learning. It is dif’s feature-flag state for agents, in one place.

An agent works by reading files in your repo. It cannot log into a feature-flag dashboard, so without a file it cannot tell which code paths are gated, what is under test, or why a dead-looking branch is still there. context.json is that file, and it is what lets an agent work with flags at all.

This post is about what is inside that file, how dif build produces it, and the one cost to plan for.

Key Takeaways

  • context.json is a file dif build emits: every active flag plus each surface’s latest learning, read by a coding agent on session start.
  • It is a build artifact, not a hand-edited file. dif build compiles the active flag files into client.ts, audiences.ts, and context.json together, so it always matches the flags in the repo.
  • An agent reads it to see which paths are gated, what is under test, and what has already been concluded, before it edits a line. That is state a dashboard behind a login cannot pass it.
  • The managed blocks in CLAUDE.md, AGENTS.md, and .cursorrules explain how flags work in the repo; context.json carries the current flag data the agent reads alongside them.
  • The tradeoff: context.json is a snapshot from the last dif build. Regenerate it in CI so the state the agent reads stays current.

What context.json contains

context.json is a machine-readable summary of the flags that are live right now. It has two parts: a list of active flags, and a map of surfaces to their latest learning. A dif build on a repo with two flags on the checkout surface emits something like:

{
  "flags": [
    {
      "id": "new-checkout",
      "surface": "checkout",
      "status": "active",
      "variants": ["off", "on"],
      "note": "ramping, 10% on mobile"
    },
    {
      "id": "checkout-cta-copy",
      "surface": "checkout",
      "status": "active",
      "variants": ["control", "benefit_led"],
      "note": "50/50 experiment, primary metric completed_checkout"
    }
  ],
  "surfaces": {
    "checkout": {
      "last_learning": "benefit-led CTA lifted completed_checkout 2.1%"
    }
  }
}

For an engineer, the useful part is the flag list: the id you call with dif("new-checkout"), the variants that call can return, and the note that says whether it is ramping or holding a split. For a PM, the useful part is surfaces: the last thing a test on checkout concluded, in one line. The agent reads both.

How dif build writes it

You never write context.json by hand. dif build generates it, the same way it generates the typed client your application imports. In one pass, dif compiles the active flag files into client.ts, audiences.ts, and context.json.

That is the last step of the ordinary loop: dif new drafts a flag, dif validate checks it, and dif build compiles it. The CLI reference documents each verb.

Because it is generated from the files, context.json cannot drift from them. Edit a flag, run dif build, and the file the agent reads reflects the change. There is no second source of truth to reconcile, which is the same reason feature flags in git stay reviewable: the repo is the source of truth.

How a coding agent reads context.json

An agent reads context.json on session start, before it edits anything. Two files make that work together. dif init writes managed blocks into CLAUDE.md, AGENTS.md, and .cursorrules that tell the agent flags are files and how the system works. context.json gives it the current data. The blocks are the rules, the file is the state.

Agents already read Markdown instruction files in the repo. The AGENTS.md standard, backed by Google, OpenAI, and Cursor, established that, and Claude Code reads CLAUDE.md the same way. context.json is the data those instructions point at.

With that state in hand, the agent sees that new-checkout is active and ramping, so it leaves the branch behind it alone. It sees checkout-cta-copy is holding a split, so it does not rewrite the call site out from under a running experiment. It sees the last learning on checkout, so it does not propose a test the team already ran. dif also installs agent skills for authoring and concluding experiments, so once the agent knows the state, it changes flags the way the repo expects.

Why a file beats a dashboard call

A dashboard can expose the same data over an API. For a coding agent, a file in the repo is better on every axis that matters:

  • No login. The agent reads a file it already has, not a UI behind an account it cannot hold.
  • No network call. The state is on disk, so reading it costs nothing and works offline.
  • Versioned. Commit the generated file and its changes show up in the pull request, next to the flag change that caused them.
  • Colocated. It travels with the code, so a checkout of any commit carries the flag state from that commit.

A dashboard’s API can answer “what is live now.” It cannot answer “what was live at the commit the agent is reading,” because its state is not versioned with the code. For an agent moving through history, or a reviewer reading a months-old PR, that difference is the whole point.

Keeping context.json current

context.json has one cost: it is a snapshot from the last dif build. If someone changes a flag and does not rebuild, the file lags the flags, and the agent reads stale state.

The fix is a build step, not a habit. Run dif build in CI, or in a pre-commit hook, so the committed context.json always matches the active flags. The same pipeline runs dif validate, so a broken flag fails the build in the same step that regenerates the file. Rebuild on every change, and the state the agent reads matches the repo.

FAQ

What is context.json in dif? A file that dif build generates, summarizing every active flag and each surface’s latest learning. A coding agent reads it on session start to know what is gated and what has already been tried, which is context a dashboard cannot pass to an agent.

How is context.json generated? By dif build. It compiles the active flag files in dif/ into a typed client.ts, an audiences.ts, and context.json in one pass. You do not edit it by hand; you regenerate it when a flag changes.

Do I need to commit context.json? It is a build artifact, so treat it like one. Commit it and its changes surface in code review, or regenerate it in CI. Either way, run dif build so the file matches the active flags before an agent or a reviewer reads it.

How does a coding agent use context.json? It reads the file at the start of a session and learns which flags are live and what each surface last concluded. That state stops it from deleting a branch behind a live flag or building a feature that is already gated.

Is context.json the same as a feature-flag dashboard export? No. An export is a point-in-time dump from a system that lives outside your repo. context.json is generated from the flag files themselves, versioned with the code, and readable with no login and no network call.

Getting started

context.json comes out of one idea: put the flag state in a file, and the agent that reads your code reads your flags too. dif build writes every active flag and each surface’s learning into that file, the agent reads it on session start, and dif validate checks the flags it writes back. The only upkeep is rebuilding so it never lags the repo.

Install the CLI and scaffold a project:

npm install -g @dif.sh/cli
dif init

dif init writes the managed CLAUDE.md and AGENTS.md blocks, and dif build emits the context.json your agent reads. The feature flags for AI agents post covers the wider workflow, and the CLI reference documents dif build and the rest of the loop.