Claude Code runs A/B tests on your workflow, and one setting turns them off
Claude Code runs A/B tests from a remote flag service that release notes never mention. How to see yours, switch them off, and why vendors should say so.
One day Claude Code’s output changed shape on me. I hadn’t asked for an update or changed how I worked, but the answers came back structured differently from the day before. So I asked Claude why. Between us we traced it to a family of settings with names like tengu_plank_river_frost, cached in a JSON file in my home directory and set by Anthropic’s servers, not by me.
Tengu is Claude Code’s internal codename. On 26 September my ~/.claude.json held 680 of those remote feature values and 11 live experiment assignments, each tagged with the variation I had been put in. None of them appears in a release note.
This post is for the people who run AI coding tools every day and the people who sign off on them. It shows how to see your own experiments, the one environment variable that switches them off, what switching off costs, and why I think vendors owe us a label on the box.
Claude Code uses GrowthBook, a feature-flag and experimentation service. At start-up it asks Anthropic’s servers which features are on for you and which experiment arms you are in, then caches the answer in ~/.claude.json. Run this to see yours:
jq -r '.cachedExperimentData // {} | to_entries[] | "\(.key)\tvariation \(.value.variationId)"' ~/.claude.jsonjq '.cachedGrowthBookFeatures | length' ~/.claude.jsonjq -r '.cachedGrowthBookFeaturesAt / 1000 | todate' ~/.claude.jsonThe first command lists the experiments you are enrolled in. On my machine it printed 11 lines, two of them on variation 1:
tengu_read_dedup_killswitch variation 1tengu_plank_river_frost variation 0tengu_ultrareview_awareness variation 1...The second counts the feature values, 680 for me. The third tells you when they were last refreshed.
The names don’t say what each experiment does. You can see that you’re enrolled, not what changed.
Three public cases. Two have an Anthropic engineer on the record; the third came from a blogger and a changelog line:
- Shorter plans. In March 2026 a developer paying $200 a month noticed plan mode had started capping plans at 40 lines. They wrote it up as Please Do Not A/B Test My Workflow. The engineer who ran the test replied on Hacker News. They had expected shorter plans to cut rate-limit hits, early results showed little effect, and they ended the experiment.
- Effort levels. In August 2026 a Hacker News thread claimed Anthropic was A/B testing reduced effort levels. A Claude Code team member answered: “We sometimes test API serving configs in Claude Code before rolling them out”, and said a running test mapped the numerical effort value differently, but “the effort you selected is the effort you’re getting”.
- Project rules. Until version 2.1.281 on 23 September 2026, a flag called
tengu_agents_md_moddecided whether Claude Code read a project’sAGENTS.mdat all. A blogger found that with telemetry off, it never did. More on that one below, because it bites the people who opt out.
I take the engineers at their word. None of this is sinister, and the people running these experiments answered in public, which plenty of vendors wouldn’t do.
That’s also the problem. Each of these came to light because a user noticed something odd and went digging. Nobody was told in advance.
Every change-management process I have run rests on the same assumption: a tool behaves the same today as it did yesterday unless someone changed it, and that change left a record. A new Claude Code version leaves a record, in the changelog and in the version string. A flag flip leaves nothing. The binary is identical, the version is identical, and the output is different.
For a practitioner that means a result you can’t reproduce. Two engineers on the same version can get different plans for the same prompt because they sit in different arms, and neither can see which arm the other is in. You debug the prompt, the repository and the model before it occurs to you to check the tool.
For a leader it’s an audit question with no good answer. If an AI agent writes code that ships, the tool that wrote it is part of your software supply chain. “Which configuration produced this change?” should be answerable. Today the honest answer is “the version we can tell you, the experiment arms we can’t, and the cache that would have told us is overwritten on the next refresh.”
I had already set DISABLE_TELEMETRY, DISABLE_ERROR_REPORTING and DO_NOT_TRACK in my ~/.claude/settings.json, on the belief that it stopped the experiments. So I checked, in the 2.1.283 binary on my laptop.
It does, but only two of the three. Claude Code works out a privacy level from the environment:
function Emt(){if(process.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC)return"essential-traffic";if(process.env.DISABLE_TELEMETRY)return"no-telemetry";if(Le(process.env.DO_NOT_TRACK))return"no-telemetry";return"default"}Anything other than default disables GrowthBook. Every flag lookup then returns the default compiled into the client:
if(!this.deps.isEnabled()&&!this.deps.isDiskCacheReadableWhileDisabled())return{value:n,source:"disabled"};The old cache on disk is ignored too, so a stale experiment arm doesn’t linger. Anthropic’s data usage page agrees: setting DISABLE_TELEMETRY or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC “also disables the feature-flag evaluation”. DISABLE_ERROR_REPORTING doesn’t; it only stops crash reports.Sidenote: The check is if(process.env.DISABLE_TELEMETRY), so any non-empty value switches telemetry off, including "0" and "false". DO_NOT_TRACK goes through a parser and needs a true-ish value.
So the setting is one line:
{ "env": { "DISABLE_TELEMETRY": "1" }}Opting out doesn’t give you a neutral Claude Code. It gives you whatever Anthropic compiled in as the default, and there are three costs.
Defaults still change with every release. Each new version can ship new defaults, so behaviour still moves, just on a schedule you can see. If reproducibility matters, pin the version as well: DISABLE_AUTOUPDATER stops the background update check, and "autoUpdatesChannel": "stable" in settings trails the latest release. Both are in the setup docs.
Some features stop working. Remote Control depends on flag evaluation and goes with it. Channels are gated on tengu_harbor, and setting CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC blocks that flag. The issue was closed as a duplicate.
Opting out can hide changes too. The AGENTS.md case is the sharpest. The flag existed so Anthropic could switch the feature off remotely if it broke something. With telemetry off the flag fell back to its default, off, and Claude Code silently ignored project rules for everyone who had opted out. It was fixed in 2.1.281. The people who opted out of silent changes got one anyway, and it hit the file that tells an agent what it may and may not do.
I still keep telemetry off. A default I can pin beats an arm I can’t see. But it’s a trade, and “I set the variable, so the tool is stable” is not true.
The best argument against me is that A/B testing is how good products get built. Anthropic can’t evaluate a plan-length change on synthetic prompts alone; it needs real users on real work, and asking every user to opt in shrinks the sample and skews it towards enthusiasts.
I accept all of that. My ask is smaller than “stop testing”:
- Show the cohort. A line in
/statuslisting the experiments this session is enrolled in, by name and arm. The data is already in~/.claude.json; it just isn’t shown. - Describe the experiment. A short public note for any experiment that changes output a user will act on: plans, code, permission prompts, which instruction files get read. UI copy and nudges can stay quiet.
- Opt in for anything that touches the work product. A flag that changes how long a plan is changes what an engineer ships. That deserves a yes from the person paying.
- Log it where the user can keep it. Write the arm into the session transcript, so the record survives the next cache refresh.
Run the three jq commands above on your own machine and on one teammate’s. If the arms differ, you have your answer to “why does Claude do that for them and not for me?”
Then decide as a team, not per laptop. If reproducibility matters more than the newest behaviour, set DISABLE_TELEMETRY and DISABLE_AUTOUPDATER in the managed settings file so nobody’s local settings override them. Record the Claude Code version in your change log next to the model. If you keep experiments on, write that down as an accepted risk, and check the jq output first when a result can’t be reproduced.
I only went looking because the output changed shape. Most people won’t notice, and nothing tells them.
More on GenAI
Who picks the model when a Claude Code workflow fans out
Workflow agents can quietly run on your priciest model. The four rungs that pick each agent's model, a probe that proves it, and how to own Claude's guide.
Give your AI workflows the least autonomy that works
Autonomy is a permission you grant a model, not a feature it has. Five levels for AI workflows, and how to pick the lowest one each step can live with.