Using dif skills for agent-driven experimentation
dif init installs more than a folder. It drops three Claude Code skills into .claude/skills/ and writes a guidance block into your agent config files, so a
coding agent can draft, edit, and conclude experiments next to you. The skills read dif/context.json and the surface logs on the way in, so prior learning travels
with the work.
What dif init put in your repo
Alongside the dif/ workspace, dif init writes:
.claude/skills/ dif-author-experiment/ # draft and iterate on an experiment dif-conclude-experiment/ # write the decision, archive, learn dif-generate-surfaces/ # propose the surface set from the codebase CLAUDE.md # a managed dif block AGENTS.md # the same block, for other agents .cursorrules # the same block, for Cursor
dif owns only its marked block in those three files, so anything else you keep there
survives a re-run. To skip all of it, pass dif init --no-agent-files. The CLI,
the SDK, and the build work the same without it.
context.json: the session-start read
dif build regenerates dif/context.json. It lives outside the
gitignored generated/ folder, so it is committed, and any agent that opens the
repo sees the current state. Think of it as a CLAUDE.md for your experiments:
{
"active": [
{ "id": "checkout-cta-v2", "surface": "checkout",
"variants": ["control", "variant_a"], "running_for_days": 7 }
],
"surfaces": [
{ "name": "checkout",
"recent_learning": "Get it today lifted conversion 2.1% on returning" }
],
"conventions": ["Fire exposure at render, never at assignment."]
}The file carries what is active, on which surface, for how long, each surface's most recent learning, and the project conventions. Because the skills read it first, a new draft starts from what the last test found instead of from a blank page.
The three skills
Each skill is a plain SKILL.md with a trigger description. Your agent loads one
when your request matches: say "draft an experiment" and dif-author-experiment answers. They follow the daily loop, and the skills reference covers each one in full.
dif-author-experiment
For drafting, editing, or fixing an experiment. It reads three files before writing
anything: dif/context.json for what is already running, the surface's ## Learnings log so it does not re-test a settled question, and dif/config.yaml for the audience attributes it may use. Then it runs the loop:
$ dif new <id> --surface <surface> # fill in the hypothesis, brief, rationale, audience, metrics $ dif validate $ dif build
It fills the stubs with opinions: one falsifiable hypothesis, variants that total 100 with control first, a single primary metric, and predicates only over declared
attributes.
dif-conclude-experiment
For closing a test that has run. The decision you write becomes the next line in the surface log, and the next draft on that surface reads it. So the skill will not conclude until it can answer four questions: is there a real analysis of the primary metric, did the test run long enough on the right traffic, does the outcome fit one sentence with a direction and a number, and did the guardrails hold.
$ dif conclude checkout-cta-v2 \ --decision "Shipped variant_a. +2.1% completed-checkout on returning, p<0.01 over 14d. Guardrails clean."
That command moves the file to concluded/, fills the ## Decision block, and appends a dated line to the surface log. A useful decision reads like the one
above. "Inconclusive." tells the next draft nothing.
dif-generate-surfaces
For a fresh repo, where dif init left a single surface. A surface is a place
you would run a test, not a route or a component, so most apps have three to eight. The
skill reads your README, your routes, and your config, proposes a list with a one-line
reason for each, and waits for your yes before it writes the files.
A session looks like this
You talk to the agent the way you would a teammate. To start a test:
Draft an experiment on checkout testing a more urgent CTA, for returning visitors.
It reads the checkout log, runs dif new, fills the frontmatter, and validates. When the numbers are in:
Conclude checkout-cta-v2. Variant A won, +2.1% over two weeks.
It writes the decision, archives the file, and appends the learning. You review the diff and commit, the same as any other change.
The skills are an accelerant, not a requirement. The CLI and SDK behave the same without
them, and the AGENTS.md and .cursorrules blocks point non-Claude
agents at the same workflow. Once a test ships, the next step is a team-wide live read, which
is what Dif Cloud adds.