What to pin before your AI tools update themselves
Find the defaults your work quietly depends on, pin the few that matter, and set up the checks that tell you when a vendor moved one.
on this page · 0 / 0 checked
You did not change anything. The script has the same flags it had last month, the repo is the same, the prompt is the same. Today it stops and waits for an approval that was never there before, or it returns a 400 on a parameter you set two years ago, or the output is subtly different and you spend an afternoon deciding whether you imagined it. Somewhere in between, a vendor moved a value you never chose. You never chose it because you took the default, and a default is theirs to move.
This is the ordinary weather of running on someone else’s tools, and it is not a scandal. Vendors ship better defaults, rename confusing ones, and retire models on a schedule they publish. What breaks is the part of your setup that depended on a value nobody wrote down. This guide is for a solo operator or a small team running AI tools in something that matters, a client deliverable, a nightly job, a support flow. It is less useful if your employer deploys managed settings to your machine, because some of the keys below are decided for you and nothing you put in your own files changes them; your job there is to run /status and find out which source applies [3].
A default is a decision someone else makes for you, on a schedule
Take Claude Code’s starting permission mode, which decides whether the agent asks you before it acts. The documentation is explicit that there is no single answer: “The built-in default depends on how you run Claude Code, on your plan, and on whether Claude Code could fetch its feature flags” [1]. A Pro, Max or Team plan in a terminal or the VS Code extension starts in auto mode. A claude -p run, an Agent SDK session, an Enterprise plan, a Console API key, or a session on Amazon Bedrock, Google Cloud’s Agent Platform or Microsoft Foundry starts in Manual, whose config value is default [1]. So does any session where feature-flag fetching is off, and your first session after you install Claude Code or upgrade to a version that adds this default, unless Claude Code fetches the flags in time after a fresh install [1].
Version matters too. The built-in auto default requires Claude Code v2.1.228 or later on macOS, Linux and WSL, and v2.1.233 or later on native Windows; on earlier versions the built-in default is Manual [1]. The Manual name itself is recent. The mode that reviews every action is now named Manual in the CLI, in claude --help, in the VS Code and JetBrains extensions and in the desktop app, its config value is still default, and both the Manual label and the manual alias require Claude Code v2.1.200 or later [1]. The config value is the one hooks and SDK integrations use, and it did not move [1]. What changed is that people who had been calling it “the default” had to notice what the default did.
Count the variables in that one setting. Your plan, your launch method, your platform, your version, a server-side flag, and whether this is your first session after an upgrade [1]. Every one of them can change without you touching a file. If your workflow depends on the answer, the answer belongs in your configuration, not in the vendor’s.
A model name is a version number, except when it is a pointer
The same trap sits one layer down, in the model ID. Anthropic’s versioning page names the assumption directly: “A common misconception is that dateless model IDs such as claude-sonnet-4-6 behave as evergreen pointers that route to the latest or best-performing version. That is not the case” [5]. For the 4.6 generation and later, the dateless ID is a fixed snapshot. Anthropic “does not update the weights or configuration of an existing model ID”, and when an updated version is available “it ships under a new model ID” [5]. Older Claude models work the other way: an alias such as claude-sonnet-4-5 is “a convenience pointer that resolves to the most recent dated snapshot for that minor version” [5].
Google’s Gemini API uses a third arrangement, and says so plainly. A latest alias such as gemini-flash-latest “will get hot-swapped with every new release of a specific model variation”, and can point at a stable, preview or experimental release [8]. Stable IDs such as gemini-3.6-flash point at a specific version and “usually don’t change” [8]. Preview models are deprecated with at least 2 weeks notice [8].
So the string you paste into your code means one of three things depending on the vendor and the generation: a frozen snapshot, a pointer that moves quietly, or a preview with a short life. Nothing in the string itself tells you which. If you are running the same prompt across Claude, ChatGPT and Gemini and comparing results, this is the first thing to check, because a pointer that moved under one of them makes the comparison meaningless and looks exactly like a real difference in quality.
The notice period is the real number to plan around
Retirement is the version of this problem that has a deadline attached, and every vendor publishes theirs. Anthropic commits to a minimum of 60 days’ notice before retiring a publicly released model, sends email to customers with active deployments, and is blunt about the end state: requests to a retired model fail [6]. The dates are concrete. claude-opus-4-1-20250805 was deprecated on 5 June 2026 and retired on 5 August 2026 [6]. claude-sonnet-4-20250514 was deprecated on 14 April 2026 and retired on 15 June 2026 [6].
OpenAI’s windows are longer and split by model class: at least 6 months for generally available models, at least 3 months for specialized variants such as chat, Codex and deep research variants, and as little as 2 weeks for preview models, with safety or compliance issues allowed to move faster [7]. A recent example runs the full length: gpt-5-2025-08-07, o3-2025-04-16 and o3-pro-2025-06-10 were announced for deprecation on 11 June 2026 with a shutdown date of 11 December 2026 [7]. Google’s commitment for a moving alias is the shortest of the three. For breaking changes, a 2-week notice arrives by email before the version behind latest changes [8].
Two weeks by email is a real constraint if the email goes to an address nobody reads. Plan around the shortest notice period you are actually exposed to, not the longest one you saw in a policy page. And note that models are not the only thing retired. Anthropic has deprecated the temperature, top_p and top_k parameters for Claude Opus 4.7 and later, which now return a 400 error when set to non-default values, with the recommendation to omit them and use prompting instead [6]. A working integration can break on a parameter, not just on a name.
Pin the few things a wrong version would cost you to undo
Pinning everything is not the goal. An agent frozen at last spring’s version accumulates its own risk, and you will be the one paying for the migration you deferred. The useful question is narrow: which values, if they changed overnight without telling me, would cost me something I cannot easily reverse. Pin those, and let the rest float.
On the model side, that usually means writing the exact ID into anything that runs unattended or that a client depends on, and treating a moving alias as a convenience for exploratory work only. Every model ID, dated or dateless, carries its own deprecation and retirement schedule, so pinning does not exempt you from the calendar [5]. It just means the change arrives when you read the notice rather than when the vendor ships.
On the tool side, Claude Code gives you a few levers of increasing bluntness. The autoUpdatesChannel setting takes "latest", the default, or "stable", which is “typically about one week old, skipping releases with major regressions” [2]. The minimumVersion setting sets a floor that background auto-updates and claude update refuse to install below [2]. And DISABLE_AUTOUPDATER set to "1" inside the env key of your settings file stops the background check, though claude update and claude install still work; blocking every update path takes DISABLE_UPDATES instead [2]. You can also install an exact version outright, by passing it to the installer as in curl -fsSL https://claude.ai/install.sh | bash -s 2.1.89 [2]. Homebrew and WinGet installs do not auto-update at all by default, and Homebrew picks a channel by cask name: claude-code tracks stable, claude-code@latest tracks latest [2]. The minimumVersion pin only constrains updates. To make Claude Code refuse to start outside a version range rather than just refuse to update, the documentation points you to the managed settings requiredMinimumVersion and requiredMaximumVersion instead [2].
Write the setting down in the file that actually wins
Pinning a value is only half the job. The other half is putting it where it takes effect, and this is where quiet failures live. Claude Code resolves a key from the highest level that sets it, in this order: managed settings, then the command line via --settings, then project local .claude/settings.local.json, then shared project .claude/settings.json, then user ~/.claude/settings.json [3]. Nothing you set overrides a managed value, apart from a short list of security-sensitive exceptions where the stricter value wins [3].
Environment variables are not a level in that stack at all. Which one applies is decided per pair: ANTHROPIC_MODEL exported in your shell applies over the model key from any file, while ANTHROPIC_DEFAULT_MODEL applies only when no file sets model [3]. Two variables, similar names, opposite behavior.
There is also a category of setting that is refused rather than overridden. Setting permissions.defaultMode to "auto" in a project’s .claude/settings.json or .claude/settings.local.json does not take effect, and Claude Code then uses the built-in default rather than a defaultMode from your user settings; setting "bypassPermissions" in those two files does not take effect either, and the session starts in Manual [1]. A checked-in file cannot hand itself more autonomy. Worth knowing before you spend an hour wondering why a teammate’s configuration does nothing on your machine.
Finally, some keys are read once at session start, so editing them mid-session changes nothing in the running session. model, effortLevel, modelSettings and outputStyle are the ones you are most likely to touch. /model switches the model mid-session and /effort changes the effort level, but outputStyle is part of the system prompt, so an edit to it applies only after /clear or a restart [3].
Build the check that catches a change in the first minute
You are not going to read three changelogs a day. What you can do is make the current state cheap to see, so that “did something move” takes 30 seconds instead of an afternoon.
Start with the version. claude --version prints an exact number such as 2.1.211 (Claude Code) [2]. claude doctor prints read-only installation and settings diagnostics without starting a session, including the result of the most recent update attempt and any settings files it rejected [2][4]. Inside a session, /status lists the settings sources loaded for that session, though it does not show which file supplied each key [3]. /permissions shows the resolved allow and deny rules actually in effect, which is the list worth reading rather than the files you think produced it [4].
When something behaves strangely and you cannot tell whether it is your configuration or the tool, claude --safe-mode launches a session with customizations disabled, including CLAUDE.md, skills, plugins, hooks, MCP servers and custom commands [4]. If the problem survives that, point CLAUDE_CONFIG_DIR at an empty directory and launch from a directory with no .claude folder to get a session that loads nothing of yours [4]. Managed settings still apply in both cases [4].
For anything running through an API, log the model ID the response reports on every call and keep it next to the output. When results drift, the log tells you in one query whether the model changed or your prompt did. That single field is worth more than any amount of after-the-fact reasoning about whether the answers feel different this week.
pins × minutes × reviews per year. Computed in the page; nothing is sent anywhere.
What still goes wrong
Pinning converts a surprise into a debt, and debts come due. A version you froze in March is a version missing six months of fixes, and the migration you avoided gets harder every month you defer it. The failure mode is not dramatic. It is a small team still on an old model in December because nobody scheduled the hour, then discovering on the retirement date that requests now fail outright [6]. The calculator above exists to make that hour visible as a real, small number, because an unbudgeted task is an unfinished one.
Notice periods also assume the notice reaches you. Anthropic emails customers with active deployments, and Google emails 2 weeks before the version behind a latest alias changes for a breaking change [6][8]. If your API key lives under an address that forwards to a shared inbox nobody opens, the policy is technically satisfied and you still find out from a failing job. Check where those emails land before you need them.
And some changes do not announce themselves the same way, because they are not deprecations. Anthropic’s 60-day commitment covers retiring a publicly released model [6]; it is a model retirement policy, not a promise about the starting permission mode on a plan tier, which the permission documentation describes as a built-in default that varies by plan, launch method, platform, version and a server-side flag [1][6]. The only protection is the boring one: the value you care about is written down somewhere you control, and you have a way to see what is actually in effect. This guide will not help against a change inside the model’s behavior at a fixed ID, which is a different problem and mostly one you catch with your own evaluations rather than with configuration.
- 01Claude Code — Choose a permission modecode.claude.com
- 02Claude Code — Advanced setupcode.claude.com
- 03Claude Code — Settingscode.claude.com
- 04Claude Code — Debug your configurationcode.claude.com
- 05Anthropic — Model IDs and versioningplatform.claude.com
- 06Anthropic — Model deprecationsplatform.claude.com
- 07OpenAI — Deprecationsdevelopers.openai.com
- 08Google — Gemini API modelsai.google.dev